diff --git a/package-lock.json b/package-lock.json index fdecc0cd..f95337a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.10", + "version": "0.4.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.10", + "version": "0.4.11", "license": "Apache-2.0", "dependencies": { "@aries-framework/anoncreds": "^0.4.0", diff --git a/package.json b/package.json index c31f4f9f..de895222 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.10", + "version": "0.4.11", "main": "build/index", "types": "build/index", "files": [ diff --git a/src/controllers/connections/ConnectionController.ts b/src/controllers/connections/ConnectionController.ts index e6844e76..f023f123 100644 --- a/src/controllers/connections/ConnectionController.ts +++ b/src/controllers/connections/ConnectionController.ts @@ -7,10 +7,11 @@ import { AriesFrameworkError, RecordNotFoundError, } from '@aries-framework/core' -import { Controller, Delete, Example, Get, Path, Post, Query, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Controller, Delete, Example, Get, Path, Post, Query, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { ConnectionRecordExample, RecordId } from '../examples' +import { HttpResponse, NotFound } from '../../error' @Tags('Connections') @Route('/connections') @@ -76,13 +77,11 @@ export class ConnectionController extends Controller { */ @Example(ConnectionRecordExample) @Get('/:connectionId') - public async getConnectionById( - @Path('connectionId') connectionId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }> - ) { + @Response(404) + public async getConnectionById(@Path('connectionId') connectionId: RecordId) { const connection = await this.agent.connections.findById(connectionId) - if (!connection) return notFoundError(404, { reason: `connection with connection id "${connectionId}" not found.` }) + if (!connection) throw new NotFound(`connection with connection id "${connectionId}" not found.`) return connection.toJSON() } @@ -93,19 +92,17 @@ export class ConnectionController extends Controller { * @param connectionId Connection identifier */ @Delete('/:connectionId') - public async deleteConnection( - @Path('connectionId') connectionId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async deleteConnection(@Path('connectionId') connectionId: RecordId) { try { this.setStatus(204) await this.agent.connections.deleteById(connectionId) } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { reason: `connection with connection id "${connectionId}" not found.` }) + throw new NotFound(`connection with connection id "${connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -120,19 +117,17 @@ export class ConnectionController extends Controller { */ @Example(ConnectionRecordExample) @Post('/:connectionId/accept-request') - public async acceptRequest( - @Path('connectionId') connectionId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async acceptRequest(@Path('connectionId') connectionId: RecordId) { try { const connection = await this.agent.connections.acceptRequest(connectionId) return connection.toJSON() } catch (error) { if (error instanceof AriesFrameworkError) { - return notFoundError(404, { reason: `connection with connection id "${connectionId}" not found.` }) + throw new NotFound(`connection with connection id "${connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -147,19 +142,17 @@ export class ConnectionController extends Controller { */ @Example(ConnectionRecordExample) @Post('/:connectionId/accept-response') - public async acceptResponse( - @Path('connectionId') connectionId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async acceptResponse(@Path('connectionId') connectionId: RecordId) { try { const connection = await this.agent.connections.acceptResponse(connectionId) return connection.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { reason: `connection with connection id "${connectionId}" not found.` }) + throw new NotFound(`connection with connection id "${connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } } diff --git a/src/controllers/credentials/CredentialController.ts b/src/controllers/credentials/CredentialController.ts index 10cd9093..f0575bcf 100644 --- a/src/controllers/credentials/CredentialController.ts +++ b/src/controllers/credentials/CredentialController.ts @@ -2,10 +2,11 @@ import type { RestAgent } from '../../utils/agent' import type { CredentialExchangeRecordProps } from '@aries-framework/core' import { CredentialRepository, CredentialState, Agent, RecordNotFoundError } from '@aries-framework/core' -import { Body, Controller, Delete, Get, Path, Post, Res, Route, Tags, TsoaResponse, Example, Query } from 'tsoa' +import { Body, Controller, Delete, Get, Path, Post, Route, Tags, Example, Query, Response } from 'tsoa' import { injectable } from 'tsyringe' import { CredentialExchangeRecordExample, RecordId } from '../examples' +import { HttpResponse, NotFound } from '../../error' import { AcceptCredentialRequestOptions, OfferCredentialOptions, @@ -57,21 +58,17 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Get('/:credentialRecordId') - public async getCredentialById( - @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async getCredentialById(@Path('credentialRecordId') credentialRecordId: RecordId) { try { const credential = await this.agent.credentials.getById(credentialRecordId) return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -81,21 +78,17 @@ export class CredentialController extends Controller { * @param credentialRecordId */ @Delete('/:credentialRecordId') - public async deleteCredential( - @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async deleteCredential(@Path('credentialRecordId') credentialRecordId: RecordId) { try { this.setStatus(204) await this.agent.credentials.deleteById(credentialRecordId) } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -108,21 +101,17 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/propose-credential') - public async proposeCredential( - @Body() options: ProposeCredentialOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async proposeCredential(@Body() options: ProposeCredentialOptions) { try { const credential = await this.agent.credentials.proposeCredential(options) return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `connection with connection record id "${options.connectionId}" not found.`, - }) + throw new NotFound(`connection with connection record id "${options.connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -136,10 +125,10 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/:credentialRecordId/accept-proposal') + @Response(404) + @Response(500) public async acceptProposal( @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() options?: AcceptCredentialProposalOptions ) { try { @@ -151,11 +140,9 @@ export class CredentialController extends Controller { return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -168,18 +155,11 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/create-offer') - public async createOffer( - @Body() options: CreateOfferOptions, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { - try { - const offer = await this.agent.credentials.createOffer(options) - return { - message: offer.message.toJSON(), - credentialRecord: offer.credentialRecord.toJSON(), - } - } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + public async createOffer(@Body() options: CreateOfferOptions) { + const offer = await this.agent.credentials.createOffer(options) + return { + message: offer.message.toJSON(), + credentialRecord: offer.credentialRecord.toJSON(), } } @@ -192,26 +172,23 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/offer-credential') - public async offerCredential( - @Body() options: OfferCredentialOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async offerCredential(@Body() options: OfferCredentialOptions) { try { //check connection exists const connection = await this.agent.connections.findById(options.connectionId) - if (!connection) - return notFoundError(404, { reason: `connection with connection id "${options.connectionId}" not found.` }) + if (!connection) throw new NotFound(`connection with connection id "${options.connectionId}" not found.`) const credential = await this.agent.credentials.offerCredential(options) return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `the credential definition id "${options.credentialFormats.anoncreds?.credentialDefinitionId}" not found.`, - }) + throw new NotFound( + `the credential definition id "${options.credentialFormats.anoncreds?.credentialDefinitionId}" not found.` + ) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -225,10 +202,10 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/:credentialRecordId/accept-offer') + @Response(404) + @Response(500) public async acceptOffer( @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() options?: AcceptCredentialOfferOptions ) { try { @@ -239,11 +216,9 @@ export class CredentialController extends Controller { return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -257,10 +232,10 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/:credentialRecordId/accept-request') + @Response(404) + @Response(500) public async acceptRequest( @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() options?: AcceptCredentialRequestOptions ) { try { @@ -271,11 +246,9 @@ export class CredentialController extends Controller { return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -288,21 +261,17 @@ export class CredentialController extends Controller { */ @Example(CredentialExchangeRecordExample) @Post('/:credentialRecordId/accept-credential') - public async acceptCredential( - @Path('credentialRecordId') credentialRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async acceptCredential(@Path('credentialRecordId') credentialRecordId: RecordId) { try { const credential = await this.agent.credentials.acceptCredential({ credentialRecordId: credentialRecordId }) return credential.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `credential with credential record id "${credentialRecordId}" not found.`, - }) + throw new NotFound(`credential with credential record id "${credentialRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } } diff --git a/src/controllers/credentials/CredentialDefinitionController.ts b/src/controllers/credentials/CredentialDefinitionController.ts index ccc1614e..a4ceb4cf 100644 --- a/src/controllers/credentials/CredentialDefinitionController.ts +++ b/src/controllers/credentials/CredentialDefinitionController.ts @@ -3,10 +3,11 @@ import type { Did, SchemaId } from '../examples' import type { AnonCredsCredentialDefinitionResponse } from '../types' import { Agent } from '@aries-framework/core' -import { Body, Controller, Example, Get, Path, Post, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Body, Controller, Example, Get, Path, Post, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { CredentialDefinitionExample, CredentialDefinitionId } from '../examples' +import { HttpResponse, NotFound, BadRequest } from '../../error' @Tags('Credential Definitions') @Route('/credential-definitions') @@ -27,11 +28,11 @@ export class CredentialDefinitionController extends Controller { */ @Example(CredentialDefinitionExample) @Get('/:credentialDefinitionId') + @Response(400) + @Response(404) + @Response(500) public async getCredentialDefinitionById( - @Path('credentialDefinitionId') credentialDefinitionId: CredentialDefinitionId, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Path('credentialDefinitionId') credentialDefinitionId: CredentialDefinitionId ): Promise { const { credentialDefinition, @@ -39,19 +40,15 @@ export class CredentialDefinitionController extends Controller { } = await this.agent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) if (error === 'notFound') { - return notFoundError(404, { - reason: `credential definition with credentialDefinitionId "${credentialDefinitionId}" not found.`, - }) + throw new NotFound(`credential definition with credentialDefinitionId "${credentialDefinitionId}" not found.`) } if (error === 'invalid' || error === 'unsupportedAnonCredsMethod') { - return badRequestError(400, { - reason: `credentialDefinitionId "${credentialDefinitionId}" has invalid structure.`, - }) + throw new BadRequest(`credentialDefinitionId "${credentialDefinitionId}" has invalid structure.`) } if (error !== undefined || credentialDefinition === undefined) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } return { @@ -68,27 +65,25 @@ export class CredentialDefinitionController extends Controller { */ @Example(CredentialDefinitionExample) @Post('/') + @Response(404) + @Response(500) public async createCredentialDefinition( @Body() credentialDefinitionRequest: { issuerId: Did schemaId: SchemaId tag: string - }, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + } ): Promise { const { resolutionMetadata: { error }, } = await this.agent.modules.anoncreds.getSchema(credentialDefinitionRequest.schemaId) if (error === 'notFound' || error === 'invalid' || error === 'unsupportedAnonCredsMethod') { - return notFoundError(404, { - reason: `schema with schemaId "${credentialDefinitionRequest.schemaId}" not found.`, - }) + throw new NotFound(`schema with schemaId "${credentialDefinitionRequest.schemaId}" not found.`) } if (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } const { @@ -103,7 +98,7 @@ export class CredentialDefinitionController extends Controller { }) if (state !== 'finished' || credentialDefinitionId === undefined || credentialDefinition === undefined) { - return internalServerError(500, { message: `something went wrong` }) + throw new HttpResponse({ message: `something went wrong creating credential definition` }) } return { diff --git a/src/controllers/credentials/SchemaController.ts b/src/controllers/credentials/SchemaController.ts index 1d9ffc92..2f9ed4b8 100644 --- a/src/controllers/credentials/SchemaController.ts +++ b/src/controllers/credentials/SchemaController.ts @@ -3,10 +3,11 @@ import type { Did, Version } from '../examples' import type { AnonCredsSchemaResponse } from '../types' import { Agent } from '@aries-framework/core' -import { Body, Example, Get, Path, Post, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Body, Example, Get, Path, Post, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { SchemaId, SchemaExample } from '../examples' +import { HttpResponse, NotFound, BadRequest } from '../../error' @Tags('Schemas') @Route('/schemas') @@ -26,30 +27,24 @@ export class SchemaController { */ @Example(SchemaExample) @Get('/:schemaId') - public async getSchemaById( - @Path('schemaId') schemaId: SchemaId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(400) + @Response(404) + @Response(500) + public async getSchemaById(@Path('schemaId') schemaId: SchemaId) { const { schema, resolutionMetadata } = await this.agent.modules.anoncreds.getSchema(schemaId) const error = resolutionMetadata?.error if (error === 'notFound') { - return notFoundError(404, { - reason: `schema definition with schemaId "${schemaId}" not found.`, - }) + throw new NotFound(`schema definition with schemaId "${schemaId}" not found.`) } if (error === 'invalid' || error === 'unsupportedAnonCredsMethod') { - return badRequestError(400, { - reason: `schemaId "${schemaId}" has invalid structure.`, - }) + throw new BadRequest(`schemaId "${schemaId}" has invalid structure.`) } if (error !== undefined || schema === undefined) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw new HttpResponse({ message: `something went wrong: schema is undefined or ${error}` }) } return { @@ -66,6 +61,7 @@ export class SchemaController { */ @Example(SchemaExample) @Post('/') + @Response(500) public async createSchema( @Body() schema: { @@ -73,8 +69,7 @@ export class SchemaController { name: string version: Version attrNames: string[] - }, - @Res() internalServerError: TsoaResponse<500, { message: string }> + } ) { const { schemaState } = await this.agent.modules.anoncreds.registerSchema({ schema: { @@ -87,11 +82,11 @@ export class SchemaController { }) if (schemaState.state === 'failed') { - return internalServerError(500, { message: `something went wrong: ${schemaState.reason}` }) + throw new HttpResponse({ message: `something went wrong: ${schemaState.reason}` }) } if (schemaState.state !== 'finished' || schemaState.schemaId === undefined || schemaState.schema === undefined) { - return internalServerError(500, { message: `something went wrong: unknown` }) + throw new HttpResponse({ message: `something went wrong creating schema: unknown` }) } return { diff --git a/src/controllers/did/DidController.ts b/src/controllers/did/DidController.ts index 0a5770a9..69a2a9e8 100644 --- a/src/controllers/did/DidController.ts +++ b/src/controllers/did/DidController.ts @@ -1,10 +1,11 @@ import type { DidCreateOptions, DidCreateResult, DidResolutionResultProps, ImportDidOptions } from '../types' import { Agent, AriesFrameworkError, TypedArrayEncoder } from '@aries-framework/core' -import { Body, Controller, Example, Get, Path, Post, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Body, Controller, Example, Get, Path, Post, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { Did, DidRecordExample, DidStateExample } from '../examples' +import { HttpResponse, BadRequest } from '../../error' @Tags('Dids') @Route('/dids') @@ -43,11 +44,9 @@ export class DidController extends Controller { */ @Example(DidRecordExample) @Post('/import') - public async importDid( - @Body() options: ImportDidOptions, - @Res() badRequestError: TsoaResponse<400, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(400) + @Response(500) + public async importDid(@Body() options: ImportDidOptions) { try { const { privateKeys, ...rest } = options await this.agent.dids.import({ @@ -60,11 +59,9 @@ export class DidController extends Controller { return this.getDidRecordByDid(options.did) } catch (error) { if (error instanceof AriesFrameworkError) { - return badRequestError(400, { - reason: `Error importing Did - ${error.message}`, - }) + throw new BadRequest(`Error importing Did - ${error.message}`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -76,14 +73,12 @@ export class DidController extends Controller { */ @Example(DidStateExample) @Post('/create') - public async createDid( - @Body() options: DidCreateOptions, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(500) + public async createDid(@Body() options: DidCreateOptions) { const { didState } = await this.agent.dids.create(options) if (didState.state === 'failed') { - return internalServerError(500, { + throw new HttpResponse({ message: `Error creating Did - ${didState.reason}`, }) } diff --git a/src/controllers/outofband/OutOfBandController.ts b/src/controllers/outofband/OutOfBandController.ts index 871ae5de..7810cb40 100644 --- a/src/controllers/outofband/OutOfBandController.ts +++ b/src/controllers/outofband/OutOfBandController.ts @@ -7,11 +7,12 @@ import type { } from '@aries-framework/core' import { AgentMessage, JsonTransformer, OutOfBandInvitation, Agent, RecordNotFoundError } from '@aries-framework/core' -import { Body, Controller, Delete, Example, Get, Path, Post, Query, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Body, Controller, Delete, Example, Get, Path, Post, Query, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { ConnectionRecordExample, outOfBandInvitationExample, outOfBandRecordExample, RecordId } from '../examples' import { AcceptInvitationConfig, ReceiveInvitationByUrlProps, ReceiveInvitationProps } from '../types' +import { HttpResponse, NotFound } from '../../error' @Tags('Out Of Band') @Route('/oob') @@ -46,14 +47,11 @@ export class OutOfBandController extends Controller { */ @Example(outOfBandRecordExample) @Get('/:outOfBandId') - public async getOutOfBandRecordById( - @Path('outOfBandId') outOfBandId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }> - ) { + @Response(404) + public async getOutOfBandRecordById(@Path('outOfBandId') outOfBandId: RecordId) { const outOfBandRecord = await this.agent.oob.findById(outOfBandId) - if (!outOfBandRecord) - return notFoundError(404, { reason: `Out of band record with id "${outOfBandId}" not found.` }) + if (!outOfBandRecord) throw new NotFound(`Out of band record with id "${outOfBandId}" not found.`) return outOfBandRecord.toJSON() } @@ -75,22 +73,17 @@ export class OutOfBandController extends Controller { }) @Post('/create-invitation') public async createInvitation( - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() config?: Omit // props removed because of issues with serialization ) { - try { - const outOfBandRecord = await this.agent.oob.createInvitation(config) - return { - invitationUrl: outOfBandRecord.outOfBandInvitation.toUrl({ - domain: this.agent.config.endpoints[0], - }), - invitation: outOfBandRecord.outOfBandInvitation.toJSON({ - useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, - }), - outOfBandRecord: outOfBandRecord.toJSON(), - } - } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + const outOfBandRecord = await this.agent.oob.createInvitation(config) + return { + invitationUrl: outOfBandRecord.outOfBandInvitation.toUrl({ + domain: this.agent.config.endpoints[0], + }), + invitation: outOfBandRecord.outOfBandInvitation.toJSON({ + useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, + }), + outOfBandRecord: outOfBandRecord.toJSON(), } } @@ -108,24 +101,19 @@ export class OutOfBandController extends Controller { }) @Post('/create-legacy-invitation') public async createLegacyInvitation( - @Res() internalServerError: TsoaResponse<500, { message: string }>, @Body() config?: Omit // routing prop removed because of issues with public key serialization ) { - try { - const { outOfBandRecord, invitation } = await this.agent.oob.createLegacyInvitation(config) + const { outOfBandRecord, invitation } = await this.agent.oob.createLegacyInvitation(config) - return { - invitationUrl: invitation.toUrl({ - domain: this.agent.config.endpoints[0], - useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, - }), - invitation: invitation.toJSON({ - useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, - }), - outOfBandRecord: outOfBandRecord.toJSON(), - } - } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + return { + invitationUrl: invitation.toUrl({ + domain: this.agent.config.endpoints[0], + useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, + }), + invitation: invitation.toJSON({ + useDidSovPrefixWhereAllowed: this.agent.config.useDidSovPrefixWhereAllowed, + }), + outOfBandRecord: outOfBandRecord.toJSON(), } } @@ -143,15 +131,15 @@ export class OutOfBandController extends Controller { invitationUrl: 'http://example.com/invitation_url', }) @Post('/create-legacy-connectionless-invitation') + @Response(404) + @Response(500) public async createLegacyConnectionlessInvitation( @Body() config: { recordId: string message: AgentMessageType domain: string - }, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + } ) { try { const agentMessage = JsonTransformer.fromJSON(config.message, AgentMessage) @@ -162,9 +150,9 @@ export class OutOfBandController extends Controller { }) } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { reason: `connection with connection id "${config.recordId}" not found.` }) + throw new NotFound(`connection with connection id "${config.recordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -181,22 +169,15 @@ export class OutOfBandController extends Controller { connectionRecord: ConnectionRecordExample, }) @Post('/receive-invitation') - public async receiveInvitation( - @Body() invitationRequest: ReceiveInvitationProps, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async receiveInvitation(@Body() invitationRequest: ReceiveInvitationProps) { const { invitation, ...config } = invitationRequest - try { - const invite = new OutOfBandInvitation({ ...invitation, handshakeProtocols: invitation.handshake_protocols }) - const { outOfBandRecord, connectionRecord } = await this.agent.oob.receiveInvitation(invite, config) + const invite = new OutOfBandInvitation({ ...invitation, handshakeProtocols: invitation.handshake_protocols }) + const { outOfBandRecord, connectionRecord } = await this.agent.oob.receiveInvitation(invite, config) - return { - outOfBandRecord: outOfBandRecord.toJSON(), - connectionRecord: connectionRecord?.toJSON(), - } - } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + return { + outOfBandRecord: outOfBandRecord.toJSON(), + connectionRecord: connectionRecord?.toJSON(), } } @@ -213,20 +194,13 @@ export class OutOfBandController extends Controller { connectionRecord: ConnectionRecordExample, }) @Post('/receive-invitation-url') - public async receiveInvitationFromUrl( - @Body() invitationRequest: ReceiveInvitationByUrlProps, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async receiveInvitationFromUrl(@Body() invitationRequest: ReceiveInvitationByUrlProps) { const { invitationUrl, ...config } = invitationRequest - try { - const { outOfBandRecord, connectionRecord } = await this.agent.oob.receiveInvitationFromUrl(invitationUrl, config) - return { - outOfBandRecord: outOfBandRecord.toJSON(), - connectionRecord: connectionRecord?.toJSON(), - } - } catch (error) { - return internalServerError(500, { message: `something went wrong: ${error}` }) + const { outOfBandRecord, connectionRecord } = await this.agent.oob.receiveInvitationFromUrl(invitationUrl, config) + return { + outOfBandRecord: outOfBandRecord.toJSON(), + connectionRecord: connectionRecord?.toJSON(), } } @@ -239,11 +213,11 @@ export class OutOfBandController extends Controller { connectionRecord: ConnectionRecordExample, }) @Post('/:outOfBandId/accept-invitation') + @Response(404) + @Response(500) public async acceptInvitation( @Path('outOfBandId') outOfBandId: RecordId, - @Body() acceptInvitationConfig: AcceptInvitationConfig, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + @Body() acceptInvitationConfig: AcceptInvitationConfig ) { try { const { outOfBandRecord, connectionRecord } = await this.agent.oob.acceptInvitation( @@ -257,11 +231,9 @@ export class OutOfBandController extends Controller { } } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `mediator with mediatorId ${acceptInvitationConfig?.mediatorId} not found`, - }) + throw new NotFound(`mediator with mediatorId ${acceptInvitationConfig?.mediatorId} not found`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -271,19 +243,17 @@ export class OutOfBandController extends Controller { * @param outOfBandId Record identifier */ @Delete('/:outOfBandId') - public async deleteOutOfBandRecord( - @Path('outOfBandId') outOfBandId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async deleteOutOfBandRecord(@Path('outOfBandId') outOfBandId: RecordId) { try { this.setStatus(204) await this.agent.oob.deleteById(outOfBandId) } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { reason: `Out of band record with id "${outOfBandId}" not found.` }) + throw new NotFound(`Out of band record with id "${outOfBandId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } } diff --git a/src/controllers/proofs/ProofController.ts b/src/controllers/proofs/ProofController.ts index 24c8ca2a..c3415cab 100644 --- a/src/controllers/proofs/ProofController.ts +++ b/src/controllers/proofs/ProofController.ts @@ -4,7 +4,7 @@ import type { AnonCredsProofRequestRestriction, AnonCredsRequestProofFormat } fr import type { ProofExchangeRecordProps } from '@aries-framework/core' import { Agent, RecordNotFoundError } from '@aries-framework/core' -import { Body, Controller, Delete, Example, Get, Path, Post, Query, Res, Route, Tags, TsoaResponse } from 'tsoa' +import { Body, Controller, Delete, Example, Get, Path, Post, Query, Route, Tags, Response } from 'tsoa' import { injectable } from 'tsyringe' import { maybeMapValues } from '../../utils/helpers' @@ -16,6 +16,7 @@ import { ProposeProofOptions, CreateProofRequestOptions, } from '../types' +import { HttpResponse, NotFound } from '../../error' const transformAttributeMarkers = (attributes?: { [key: string]: boolean }) => { if (!attributes) { @@ -117,23 +118,19 @@ export class ProofController extends Controller { * @returns ProofExchangeRecordProps */ @Get('/:proofRecordId') + @Response(404) + @Response(500) @Example(ProofRecordExample) - public async getProofById( - @Path('proofRecordId') proofRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + public async getProofById(@Path('proofRecordId') proofRecordId: RecordId) { try { const proof = await this.agent.proofs.getById(proofRecordId) return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `proof with proofRecordId "${proofRecordId}" not found.`, - }) + throw new NotFound(`proof with proofRecordId "${proofRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -143,21 +140,17 @@ export class ProofController extends Controller { * @param proofRecordId */ @Delete('/:proofRecordId') - public async deleteProof( - @Path('proofRecordId') proofRecordId: RecordId, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async deleteProof(@Path('proofRecordId') proofRecordId: RecordId) { try { this.setStatus(204) await this.agent.proofs.deleteById(proofRecordId) } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `proof with proofRecordId "${proofRecordId}" not found.`, - }) + throw new NotFound(`proof with proofRecordId "${proofRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -170,22 +163,18 @@ export class ProofController extends Controller { */ @Post('/propose-proof') @Example(ProofRecordExample) - public async proposeProof( - @Body() proposal: ProposeProofOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async proposeProof(@Body() proposal: ProposeProofOptions) { try { const proof = await this.agent.proofs.proposeProof(proposal) return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `connection with connectionId "${proposal.connectionId}" not found.`, - }) + throw new NotFound(`connection with connectionId "${proposal.connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -199,12 +188,12 @@ export class ProofController extends Controller { */ @Post('/:proofRecordId/accept-proposal') @Example(ProofRecordExample) + @Response(404) + @Response(500) public async acceptProposal( @Path('proofRecordId') proofRecordId: string, @Body() - proposal: AcceptProofProposalOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + proposal: AcceptProofProposalOptions ) { try { const proof = await this.agent.proofs.acceptProposal({ @@ -215,11 +204,9 @@ export class ProofController extends Controller { return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `proof with proofRecordId "${proofRecordId}" not found.`, - }) + throw new NotFound(`proof with proofRecordId "${proofRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -257,11 +244,9 @@ export class ProofController extends Controller { */ @Post('/request-proof') @Example(ProofRecordExample) - public async requestProof( - @Body() request: RequestProofOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async requestProof(@Body() request: RequestProofOptions) { const { connectionId, proofFormats, ...rest } = request try { const proof = await this.agent.proofs.requestProof({ @@ -275,11 +260,9 @@ export class ProofController extends Controller { return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `connection with connectionId "${connectionId}" not found.`, - }) + throw new NotFound(`connection with connectionId "${connectionId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -293,12 +276,12 @@ export class ProofController extends Controller { */ @Post('/:proofRecordId/accept-request') @Example(ProofRecordExample) + @Response(404) + @Response(500) public async acceptRequest( @Path('proofRecordId') proofRecordId: string, @Body() - request: AcceptProofRequestOptions, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> + request: AcceptProofRequestOptions ) { try { const retrievedCredentials = await this.agent.proofs.selectCredentialsForRequest({ @@ -314,11 +297,9 @@ export class ProofController extends Controller { return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `proof with proofRecordId "${proofRecordId}" not found.`, - }) + throw new NotFound(`proof with proofRecordId "${proofRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } @@ -331,22 +312,18 @@ export class ProofController extends Controller { */ @Post('/:proofRecordId/accept-presentation') @Example(ProofRecordExample) - public async acceptPresentation( - @Path('proofRecordId') proofRecordId: string, - @Res() notFoundError: TsoaResponse<404, { reason: string }>, - @Res() internalServerError: TsoaResponse<500, { message: string }> - ) { + @Response(404) + @Response(500) + public async acceptPresentation(@Path('proofRecordId') proofRecordId: string) { try { const proof = await this.agent.proofs.acceptPresentation({ proofRecordId }) return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { - return notFoundError(404, { - reason: `proof with proofRecordId "${proofRecordId}" not found.`, - }) + throw new NotFound(`proof with proofRecordId "${proofRecordId}" not found.`) } - return internalServerError(500, { message: `something went wrong: ${error}` }) + throw error } } } diff --git a/tsconfig.json b/tsconfig.json index 07036c47..59fcf79a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "compilerOptions": { "paths": { "@aries-framework/rest": ["./src"], - "@src": ["src"], + "@src": ["./src"], "@src/*": ["./src/*"], "@schema/*": ["./schema/*"] },