From b5fe06d6425a9b38b41a73fefde1b06df5907cc5 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Tue, 25 Oct 2022 18:12:41 -0300 Subject: [PATCH 01/38] feat(common): add error options object add error options object to HttpException constructor to allow use of error cause along with custom message. --- packages/common/exceptions/http.exception.ts | 29 ++++++++++++++++--- .../test/exceptions/http.exception.spec.ts | 14 +++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 540844298e1..9eb46082a3d 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -1,5 +1,9 @@ import { isObject, isString } from '../utils/shared.utils'; +export type HttpExceptionOptions = { + cause?: Error; +}; + /** * Defines the base Nest HTTP exception, which is handled by the default * Exceptions Handler. @@ -13,12 +17,22 @@ export class HttpException extends Error { * Instantiate a plain HTTP Exception. * * @example - * `throw new HttpException()` + * throw new HttpException() + * throw new HttpException('message', HttpStatus.BAD_REQUEST) + * throw new HttpException({ reason: 'this can be a human readable reason' }, HttpStatus.BAD_REQUEST) + * throw new HttpException(new Error('Cause Error'), HttpStatus.BAD_REQUEST) + * throw new HttpException('custom message', HttpStatus.BAD_REQUEST, { + * cause: new Error('Cause Error'), + * }) + * * * @usageNotes * The constructor arguments define the response and the HTTP response status code. - * - The `response` argument (required) defines the JSON response body. + * - The `response` argument (required) defines the JSON response body. alternatively, it can also be + * an error object that is used to define an error [cause](https://nodejs.org/en/blog/release/v16.9.0/#error-cause). * - The `status` argument (required) defines the HTTP Status Code. + * - The `options` argument (optional) defines additional error options. Currently, it supports the `cause` attribute, + * and can be used as an alternative way to specify the error cause: `const error = new HttpException('description', 400, { cause: new Error() });` * * By default, the JSON response body contains two properties: * - `statusCode`: the Http Status Code. @@ -31,12 +45,14 @@ export class HttpException extends Error { * The `status` argument is required, and should be a valid HTTP status code. * Best practice is to use the `HttpStatus` enum imported from `nestjs/common`. * - * @param response string or object describing the error condition. + * @param response string, object describing the error condition or the error cause. * @param status HTTP response status code. + * @param options An object used to add an error cause. */ constructor( private readonly response: string | Record, private readonly status: number, + private readonly options?: HttpExceptionOptions, ) { super(); this.initMessage(); @@ -53,7 +69,12 @@ export class HttpException extends Error { * - https://nodejs.org/en/blog/release/v16.9.0/#error-cause * - https://github.com/microsoft/TypeScript/issues/45167 */ - public initCause() { + public initCause(): void { + if (this.options?.cause) { + this.cause = this.options.cause; + return; + } + if (this.response instanceof Error) { this.cause = this.response; } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index a880c1bfc53..6c1cd6bd003 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -139,5 +139,19 @@ describe('HttpException', () => { expect(cause).to.be.eql(message); }); + + it('configures a cause when message is a string and the options object is passed', () => { + const causeError = new Error('Some Error'); + + const customDescription = 'custom description'; + const error = new HttpException(customDescription, 400, { + cause: causeError, + }); + + expect(`${error}`).to.be.eql(`HttpException: ${customDescription}`); + const { cause } = error; + + expect(cause).to.be.eql(causeError); + }); }); }); From f5edb0f2a0fe39b28cb5f9e060c29b47575bbffe Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 09:35:18 -0300 Subject: [PATCH 02/38] chore(common): add deprecated warning add deprecated warning for HttpException class when using the first argument as the error cause. --- packages/common/exceptions/http.exception.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 9eb46082a3d..8c908a56812 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -1,3 +1,4 @@ +import { Logger } from '../services'; import { isObject, isString } from '../utils/shared.utils'; export type HttpExceptionOptions = { @@ -76,6 +77,9 @@ export class HttpException extends Error { } if (this.response instanceof Error) { + Logger.warn( + 'Deprecated: Passing the error cause as the first argument to HttpException constructor is deprecated. You should use the "options" parameter instead: new HttpException("message", 400, { cause: new Error("Some Error") }) ', + ); this.cause = this.response; } } From 587fbaefe543b86e8e4170991add3c16a911bb2f Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 14:14:55 -0300 Subject: [PATCH 03/38] feat(common): add error cause option add error cause option to bad request exception. --- .../common/exceptions/bad-request.exception.ts | 18 +++++++++++++++--- .../test/exceptions/http.exception.spec.ts | 13 +++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index 3d93e229b2c..f2368a0f8ee 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -1,5 +1,6 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { isString } from '../utils/shared.utils'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Bad Request* type errors. @@ -31,12 +32,22 @@ export class BadRequestException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions a short description of the HTTP error. */ constructor( objectOrError?: string | object | any, - description = 'Bad Request', + descriptionOrOptions: + | string + | (HttpExceptionOptions & { description?: string }) = 'Bad Request', ) { + const description = isString(descriptionOrOptions) + ? descriptionOrOptions + : descriptionOrOptions.description; + + const httpExceptionOptions = isString(descriptionOrOptions) + ? {} + : descriptionOrOptions; + super( HttpException.createBody( objectOrError, @@ -44,6 +55,7 @@ export class BadRequestException extends HttpException { HttpStatus.BAD_REQUEST, ), HttpStatus.BAD_REQUEST, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 6c1cd6bd003..48b358ae5ae 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -153,5 +153,18 @@ describe('HttpException', () => { expect(cause).to.be.eql(causeError); }); + + it('configures a cause when using a built-in exception with options', () => { + const causeError = new Error('Some Error'); + + const customDescription = 'custom description'; + const error = new BadRequestException(customDescription, { + cause: causeError, + }); + + const { cause } = error; + + expect(cause).to.be.eql(causeError); + }); }); }); From 071c4c5db9cab5699def9e74599889d4b8934082 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 14:20:15 -0300 Subject: [PATCH 04/38] refactor(common): change parameter assignment change BadRequestException constructor parameters assignment to be clearer. --- .../common/exceptions/bad-request.exception.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index f2368a0f8ee..b2ee839011c 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -40,13 +40,16 @@ export class BadRequestException extends HttpException { | string | (HttpExceptionOptions & { description?: string }) = 'Bad Request', ) { - const description = isString(descriptionOrOptions) - ? descriptionOrOptions - : descriptionOrOptions.description; + let description: string; + let httpExceptionOptions: HttpExceptionOptions; - const httpExceptionOptions = isString(descriptionOrOptions) - ? {} - : descriptionOrOptions; + if (isString(descriptionOrOptions)) { + description = descriptionOrOptions; + httpExceptionOptions = {}; + } else { + description = descriptionOrOptions.description; + httpExceptionOptions = descriptionOrOptions; + } super( HttpException.createBody( From d63b6dfadeb03fbdce087fb139b9136dd4bc5036 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 15:10:18 -0300 Subject: [PATCH 05/38] refactor(common): rearrange test blocks rearrange HttpException spec file test blocks to increase readability, better separating tests by methods and contexts. --- .../test/exceptions/http.exception.spec.ts | 123 +++++++++--------- 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 48b358ae5ae..6b1082c8df2 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -6,51 +6,59 @@ import { } from '../../exceptions'; describe('HttpException', () => { - it('should return a response as a string when input is a string', () => { - const message = 'My error message'; - expect(new HttpException(message, 404).getResponse()).to.be.eql( - 'My error message', - ); - }); - - it('should return a response as an object when input is an object', () => { - const message = { - msg: 'My error message', - reason: 'this can be a human readable reason', - anything: 'else', - }; - expect(new HttpException(message, 404).getResponse()).to.be.eql(message); - }); + describe('getResponse', () => { + it('should return a response as a string when input is a string', () => { + const message = 'My error message'; + expect(new HttpException(message, 404).getResponse()).to.be.eql( + 'My error message', + ); + }); - it('should return a message from a built-in exception as an object', () => { - const message = 'My error message'; - expect(new BadRequestException(message).getResponse()).to.be.eql({ - statusCode: 400, - error: 'Bad Request', - message: 'My error message', + it('should return a response as an object when input is an object', () => { + const message = { + msg: 'My error message', + reason: 'this can be a human readable reason', + anything: 'else', + }; + expect(new HttpException(message, 404).getResponse()).to.be.eql(message); }); - }); - it('should return an object even when the message is undefined', () => { - expect(new BadRequestException().getResponse()).to.be.eql({ - statusCode: 400, - message: 'Bad Request', + it('should return a message from a built-in exception as an object', () => { + const message = 'My error message'; + expect(new BadRequestException(message).getResponse()).to.be.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'My error message', + }); }); - }); - it('should return a status code', () => { - expect(new BadRequestException().getStatus()).to.be.eql(400); - expect(new NotFoundException().getStatus()).to.be.eql(404); + it('should return an object even when the message is undefined', () => { + expect(new BadRequestException().getResponse()).to.be.eql({ + statusCode: 400, + message: 'Bad Request', + }); + }); }); - it('should return a response', () => { - expect(new BadRequestException().getResponse()).to.be.eql({ - message: 'Bad Request', - statusCode: 400, + describe('built-in exceptions', () => { + describe('getStatus', () => { + it('should return given status code', () => { + expect(new BadRequestException().getStatus()).to.be.eql(400); + expect(new NotFoundException().getStatus()).to.be.eql(404); + }); }); - expect(new NotFoundException().getResponse()).to.be.eql({ - message: 'Not Found', - statusCode: 404, + + describe('getResponse', () => { + it('should return a response with default message and status code', () => { + expect(new BadRequestException().getResponse()).to.be.eql({ + message: 'Bad Request', + statusCode: 400, + }); + expect(new NotFoundException().getResponse()).to.be.eql({ + message: 'Not Found', + statusCode: 404, + }); + }); }); }); @@ -59,31 +67,28 @@ describe('HttpException', () => { expect(error instanceof Error).to.be.true; }); - it('should be serializable', () => { - const message = 'Some Error'; - const error = new HttpException(message, 400); - expect(`${error}`).to.be.eql(`HttpException: ${message}`); - }); + describe('when serializing', () => { + describe('and "response" parameter is a string', () => { + it('should concatenate HttpException with the given message', () => { + const responseAsString = 'Some Error'; + const error = new HttpException(responseAsString, 400); + expect(`${error}`).to.be.eql(`HttpException: ${responseAsString}`); + expect(`${error}`.includes('[object Object]')).to.not.be.true; + }); + }); - describe('when "response" is an object', () => { - it('should use default message', () => { - const obj = { foo: 'bar' }; - const error = new HttpException(obj, 400); - const badRequestError = new BadRequestException(obj); + describe('and "response" parameter is an object', () => { + it('should use default message', () => { + const responseAsObject = { foo: 'bar' }; + const error = new HttpException(responseAsObject, 400); + const badRequestError = new BadRequestException(responseAsObject); - expect(`${error}`).to.be.eql(`HttpException: Http Exception`); - expect(`${badRequestError}`).to.be.eql( - `BadRequestException: Bad Request Exception`, - ); - expect(`${error}`.includes('[object Object]')).to.not.be.true; - expect(`${badRequestError}`.includes('[object Object]')).to.not.be.true; - }); - describe('otherwise', () => { - it('should concat strings', () => { - const test = 'test message'; - const error = new HttpException(test, 400); - expect(`${error}`).to.be.eql(`HttpException: ${test}`); + expect(`${error}`).to.be.eql(`HttpException: Http Exception`); + expect(`${badRequestError}`).to.be.eql( + `BadRequestException: Bad Request Exception`, + ); expect(`${error}`.includes('[object Object]')).to.not.be.true; + expect(`${badRequestError}`.includes('[object Object]')).to.not.be.true; }); }); }); From 7e763fa0ac8ce235ff58c357b0af665aff1b064b Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 15:22:48 -0300 Subject: [PATCH 06/38] refactor(common): rename method parameter rename HttpException createBody method parameter to better represent its usage. When this parameter is a string, it is used as a value to a 'message' key in the final object. --- packages/common/exceptions/http.exception.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 8c908a56812..6e3f35ff1e4 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -112,15 +112,16 @@ export class HttpException extends Error { } public static createBody( - objectOrError: object | string, + objectOrErrorMessage: object | string, description?: string, statusCode?: number, ) { - if (!objectOrError) { + if (!objectOrErrorMessage) { return { statusCode, message: description }; } - return isObject(objectOrError) && !Array.isArray(objectOrError) - ? objectOrError - : { statusCode, message: objectOrError, error: description }; + return isObject(objectOrErrorMessage) && + !Array.isArray(objectOrErrorMessage) + ? objectOrErrorMessage + : { statusCode, message: objectOrErrorMessage, error: description }; } } From 1a8ada50c1428b7d701114f0995d4e75300f4338 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Wed, 26 Oct 2022 15:38:10 -0300 Subject: [PATCH 07/38] test(common): add http exception test add test for HttpException's getResponse method when used with a built-in exception and providing the "description" parameter as part of the "options" object. --- .../common/test/exceptions/http.exception.spec.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 6b1082c8df2..e2f31f1acc8 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -59,6 +59,18 @@ describe('HttpException', () => { statusCode: 404, }); }); + + it('should return a response with an "error" attribute when description was provided as the "option" object', () => { + const badRequestError = new BadRequestException('ErrorMessage', { + description: 'Some error description', + }); + + expect(badRequestError.getResponse()).to.be.eql({ + message: 'ErrorMessage', + error: 'Some error description', + statusCode: 400, + }); + }); }); }); From 4ded779f1fb48a74ff4cbc3ce253a66fb2ff84b7 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 12:11:25 -0300 Subject: [PATCH 08/38] refactor(common): add description attribute add description attribute to HttpExceptionOptions interface so we can reuse it among children exceptions. --- packages/common/exceptions/bad-request.exception.ts | 4 +--- packages/common/exceptions/http.exception.ts | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index b2ee839011c..4f07d3cdfdc 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -36,9 +36,7 @@ export class BadRequestException extends HttpException { */ constructor( objectOrError?: string | object | any, - descriptionOrOptions: - | string - | (HttpExceptionOptions & { description?: string }) = 'Bad Request', + descriptionOrOptions: string | HttpExceptionOptions = 'Bad Request', ) { let description: string; let httpExceptionOptions: HttpExceptionOptions; diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 6e3f35ff1e4..9bfc5831fd8 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -1,9 +1,10 @@ import { Logger } from '../services'; import { isObject, isString } from '../utils/shared.utils'; -export type HttpExceptionOptions = { +export interface HttpExceptionOptions { cause?: Error; -}; + description?: string; +} /** * Defines the base Nest HTTP exception, which is handled by the default From c5c818e8b7a4b0d500a4a134c1be2ce0bb744b5b Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 15:25:41 -0300 Subject: [PATCH 09/38] chore(common): change deprecated message --- packages/common/exceptions/http.exception.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 9bfc5831fd8..ef5c69ad2a0 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -79,7 +79,7 @@ export class HttpException extends Error { if (this.response instanceof Error) { Logger.warn( - 'Deprecated: Passing the error cause as the first argument to HttpException constructor is deprecated. You should use the "options" parameter instead: new HttpException("message", 400, { cause: new Error("Some Error") }) ', + 'DEPRECATED! Passing the error cause as the first argument to HttpException constructor is deprecated. You should use the "options" parameter instead: new HttpException("message", 400, { cause: new Error("Some Error") }) ', ); this.cause = this.response; } From 60cb953e59d96e840f36a0f06d62973a0684dbe4 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 15:31:39 -0300 Subject: [PATCH 10/38] feat(common): add error cause option add error cause option to BadGatewayException. --- .../common/exceptions/bad-gateway.exception.ts | 18 +++++++++++++++--- .../test/exceptions/http.exception.spec.ts | 15 ++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/common/exceptions/bad-gateway.exception.ts b/packages/common/exceptions/bad-gateway.exception.ts index 83ae75507bd..0414b082963 100644 --- a/packages/common/exceptions/bad-gateway.exception.ts +++ b/packages/common/exceptions/bad-gateway.exception.ts @@ -1,5 +1,6 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { isString } from '../utils/shared.utils'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Bad Gateway* type errors. @@ -31,12 +32,22 @@ export class BadGatewayException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions a short description of the HTTP error. */ constructor( objectOrError?: string | object | any, - description = 'Bad Gateway', + descriptionOrOptions: string | HttpExceptionOptions = 'Bad Gateway', ) { + let description: string; + let httpExceptionOptions: HttpExceptionOptions; + + if (isString(descriptionOrOptions)) { + description = descriptionOrOptions; + httpExceptionOptions = {}; + } else { + description = descriptionOrOptions.description; + httpExceptionOptions = descriptionOrOptions; + } super( HttpException.createBody( objectOrError, @@ -44,6 +55,7 @@ export class BadGatewayException extends HttpException { HttpStatus.BAD_GATEWAY, ), HttpStatus.BAD_GATEWAY, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index e2f31f1acc8..cc269fad3df 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { + BadGatewayException, BadRequestException, HttpException, NotFoundException, @@ -148,6 +149,9 @@ describe('HttpException', () => { }); describe('initCause', () => { + const errorCause = new Error('An internal error cause'); + const customDescription = 'custom description'; + it('configures a cause when message is an instance of error', () => { const message = new Error('Some Error'); const error = new HttpException(message, 400); @@ -171,17 +175,14 @@ describe('HttpException', () => { expect(cause).to.be.eql(causeError); }); - it('configures a cause when using a built-in exception with options', () => { - const causeError = new Error('Some Error'); - - const customDescription = 'custom description'; - const error = new BadRequestException(customDescription, { - cause: causeError, + it('configures a cause when using a BadGatewayException with options', () => { + const error = new BadGatewayException(customDescription, { + cause: errorCause, }); const { cause } = error; - expect(cause).to.be.eql(causeError); + expect(cause).to.be.eql(errorCause); }); }); }); From 7a710354c44f7100d607f0d960ed7089ae861e6b Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 15:46:03 -0300 Subject: [PATCH 11/38] refactor(common): extract description and options extract functions that provide valid values for description and http exception options to the HttpException class --- .../common/exceptions/bad-gateway.exception.ts | 12 +++--------- .../common/exceptions/bad-request.exception.ts | 15 ++++----------- packages/common/exceptions/http.exception.ts | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/common/exceptions/bad-gateway.exception.ts b/packages/common/exceptions/bad-gateway.exception.ts index 0414b082963..0cb53f36248 100644 --- a/packages/common/exceptions/bad-gateway.exception.ts +++ b/packages/common/exceptions/bad-gateway.exception.ts @@ -38,16 +38,10 @@ export class BadGatewayException extends HttpException { objectOrError?: string | object | any, descriptionOrOptions: string | HttpExceptionOptions = 'Bad Gateway', ) { - let description: string; - let httpExceptionOptions: HttpExceptionOptions; + const description = HttpException.getDescriptionFrom(descriptionOrOptions); + const httpExceptionOptions = + HttpException.getHttpExceptionOptionsFrom(descriptionOrOptions); - if (isString(descriptionOrOptions)) { - description = descriptionOrOptions; - httpExceptionOptions = {}; - } else { - description = descriptionOrOptions.description; - httpExceptionOptions = descriptionOrOptions; - } super( HttpException.createBody( objectOrError, diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index 4f07d3cdfdc..389aa805ef5 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -1,5 +1,5 @@ +import { isString } from 'class-validator'; import { HttpStatus } from '../enums/http-status.enum'; -import { isString } from '../utils/shared.utils'; import { HttpException, HttpExceptionOptions } from './http.exception'; /** @@ -38,16 +38,9 @@ export class BadRequestException extends HttpException { objectOrError?: string | object | any, descriptionOrOptions: string | HttpExceptionOptions = 'Bad Request', ) { - let description: string; - let httpExceptionOptions: HttpExceptionOptions; - - if (isString(descriptionOrOptions)) { - description = descriptionOrOptions; - httpExceptionOptions = {}; - } else { - description = descriptionOrOptions.description; - httpExceptionOptions = descriptionOrOptions; - } + const description = HttpException.getDescriptionFrom(descriptionOrOptions); + const httpExceptionOptions = + HttpException.getHttpExceptionOptionsFrom(descriptionOrOptions); super( HttpException.createBody( diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index ef5c69ad2a0..236621502c0 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -125,4 +125,18 @@ export class HttpException extends Error { ? objectOrErrorMessage : { statusCode, message: objectOrErrorMessage, error: description }; } + + public static getDescriptionFrom( + descriptionOrOptions: string | HttpExceptionOptions, + ): string { + return isString(descriptionOrOptions) + ? descriptionOrOptions + : descriptionOrOptions?.description; + } + + public static getHttpExceptionOptionsFrom( + descriptionOrOptions: string | HttpExceptionOptions, + ): HttpExceptionOptions { + return isString(descriptionOrOptions) ? {} : descriptionOrOptions; + } } From a4a85578479cef7475037e71092fe0be16b5384f Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:06:15 -0300 Subject: [PATCH 12/38] refactor(common): extract description and options create HttpException#extractDescriptionAndOptionsFrom method to return both description and options at the same time --- .../exceptions/bad-gateway.exception.ts | 5 ++--- .../exceptions/bad-request.exception.ts | 5 ++--- packages/common/exceptions/http.exception.ts | 22 +++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/common/exceptions/bad-gateway.exception.ts b/packages/common/exceptions/bad-gateway.exception.ts index 0cb53f36248..84e82c81901 100644 --- a/packages/common/exceptions/bad-gateway.exception.ts +++ b/packages/common/exceptions/bad-gateway.exception.ts @@ -38,9 +38,8 @@ export class BadGatewayException extends HttpException { objectOrError?: string | object | any, descriptionOrOptions: string | HttpExceptionOptions = 'Bad Gateway', ) { - const description = HttpException.getDescriptionFrom(descriptionOrOptions); - const httpExceptionOptions = - HttpException.getHttpExceptionOptionsFrom(descriptionOrOptions); + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); super( HttpException.createBody( diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index 389aa805ef5..dbcd7110479 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -38,9 +38,8 @@ export class BadRequestException extends HttpException { objectOrError?: string | object | any, descriptionOrOptions: string | HttpExceptionOptions = 'Bad Request', ) { - const description = HttpException.getDescriptionFrom(descriptionOrOptions); - const httpExceptionOptions = - HttpException.getHttpExceptionOptionsFrom(descriptionOrOptions); + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); super( HttpException.createBody( diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 236621502c0..6a403faed95 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -6,6 +6,11 @@ export interface HttpExceptionOptions { description?: string; } +export interface DescriptionAndOptions { + description?: string; + httpExceptionOptions?: HttpExceptionOptions; +} + /** * Defines the base Nest HTTP exception, which is handled by the default * Exceptions Handler. @@ -139,4 +144,21 @@ export class HttpException extends Error { ): HttpExceptionOptions { return isString(descriptionOrOptions) ? {} : descriptionOrOptions; } + + public static extractDescriptionAndOptionsFrom( + descriptionOrOptions: string | HttpExceptionOptions, + ): DescriptionAndOptions { + const description = isString(descriptionOrOptions) + ? descriptionOrOptions + : descriptionOrOptions?.description; + + const httpExceptionOptions = isString(descriptionOrOptions) + ? {} + : descriptionOrOptions; + + return { + description, + httpExceptionOptions, + }; + } } From 5a186af18dc0ad5e3e58944d62fac4e73c72fa0c Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:08:49 -0300 Subject: [PATCH 13/38] docs(common): add static method docs add docs for HttpException.getHttpExceptionOptionsFrom explaining its intended usage. --- packages/common/exceptions/http.exception.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/common/exceptions/http.exception.ts b/packages/common/exceptions/http.exception.ts index 6a403faed95..bc166a8a118 100644 --- a/packages/common/exceptions/http.exception.ts +++ b/packages/common/exceptions/http.exception.ts @@ -145,6 +145,11 @@ export class HttpException extends Error { return isString(descriptionOrOptions) ? {} : descriptionOrOptions; } + /** + * Utility method used to extract the error description and httpExceptionOptions from the given argument. + * This is used by inheriting classes to correctly parse both options. + * @returns the error description and the httpExceptionOptions as an object. + */ public static extractDescriptionAndOptionsFrom( descriptionOrOptions: string | HttpExceptionOptions, ): DescriptionAndOptions { From 86c5084add258ced4a6ef2a70eb0476d59568cb1 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:10:40 -0300 Subject: [PATCH 14/38] test(common): test error cause option test error cause option for BadRequestException. --- packages/common/test/exceptions/http.exception.spec.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index cc269fad3df..dcdd8802af8 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -184,5 +184,15 @@ describe('HttpException', () => { expect(cause).to.be.eql(errorCause); }); + + it('configures a cause when using a BadRequestException with options', () => { + const error = new BadRequestException(customDescription, { + cause: errorCause, + }); + + const { cause } = error; + + expect(cause).to.be.eql(errorCause); + }); }); }); From 472c7111270ef15a9d4ac0d6462f4c0eda3b839f Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:12:55 -0300 Subject: [PATCH 15/38] test(common): aggregate exception tests aggregate HttpException children classes tests in a single run to reduce the code duplication --- .../test/exceptions/http.exception.spec.ts | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index dcdd8802af8..c179d507f2c 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -175,24 +175,18 @@ describe('HttpException', () => { expect(cause).to.be.eql(causeError); }); - it('configures a cause when using a BadGatewayException with options', () => { - const error = new BadGatewayException(customDescription, { - cause: errorCause, - }); + it('configures a cause when using a bult-in exception with options', () => { + const builInErrorClasses = [BadGatewayException, BadRequestException]; - const { cause } = error; + builInErrorClasses.forEach(ExceptionClass => { + const error = new ExceptionClass(customDescription, { + cause: errorCause, + }); - expect(cause).to.be.eql(errorCause); - }); + const { cause } = error; - it('configures a cause when using a BadRequestException with options', () => { - const error = new BadRequestException(customDescription, { - cause: errorCause, + expect(cause).to.be.eql(errorCause); }); - - const { cause } = error; - - expect(cause).to.be.eql(errorCause); }); }); }); From 88ac6aa4631578d9af02635bcb38736a904fba92 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:16:03 -0300 Subject: [PATCH 16/38] feat(common): add error cause option add error cause option to ConflictException. --- packages/common/exceptions/conflict.exception.ts | 15 +++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 7 ++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/common/exceptions/conflict.exception.ts b/packages/common/exceptions/conflict.exception.ts index 93322515ef9..f7810ffbed2 100644 --- a/packages/common/exceptions/conflict.exception.ts +++ b/packages/common/exceptions/conflict.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Conflict* type errors. @@ -18,7 +18,7 @@ export class ConflictException extends HttpException { * @usageNotes * The HTTP response status code will be 409. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 409. @@ -31,12 +31,19 @@ export class ConflictException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ - constructor(objectOrError?: string | object | any, description = 'Conflict') { + constructor( + objectOrError?: string | object | any, + descriptionOrOptions: string | HttpExceptionOptions = 'Conflict', + ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody(objectOrError, description, HttpStatus.CONFLICT), HttpStatus.CONFLICT, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index c179d507f2c..f05612a7f97 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { BadGatewayException, BadRequestException, + ConflictException, HttpException, NotFoundException, } from '../../exceptions'; @@ -176,7 +177,11 @@ describe('HttpException', () => { }); it('configures a cause when using a bult-in exception with options', () => { - const builInErrorClasses = [BadGatewayException, BadRequestException]; + const builInErrorClasses = [ + BadGatewayException, + BadRequestException, + ConflictException, + ]; builInErrorClasses.forEach(ExceptionClass => { const error = new ExceptionClass(customDescription, { From 1dff9c00018858d26800c742df2fccb858ae34d9 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:17:50 -0300 Subject: [PATCH 17/38] docs(common): update exception docs update HttpException children classes docs to reflect the changes to the "description" parameter --- packages/common/exceptions/bad-gateway.exception.ts | 4 ++-- packages/common/exceptions/bad-request.exception.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/bad-gateway.exception.ts b/packages/common/exceptions/bad-gateway.exception.ts index 84e82c81901..ba46421b571 100644 --- a/packages/common/exceptions/bad-gateway.exception.ts +++ b/packages/common/exceptions/bad-gateway.exception.ts @@ -19,7 +19,7 @@ export class BadGatewayException extends HttpException { * @usageNotes * The HTTP response status code will be 502. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 502. @@ -32,7 +32,7 @@ export class BadGatewayException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param descriptionOrOptions a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, diff --git a/packages/common/exceptions/bad-request.exception.ts b/packages/common/exceptions/bad-request.exception.ts index dbcd7110479..b9f04fe6256 100644 --- a/packages/common/exceptions/bad-request.exception.ts +++ b/packages/common/exceptions/bad-request.exception.ts @@ -19,7 +19,7 @@ export class BadRequestException extends HttpException { * @usageNotes * The HTTP response status code will be 400. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 400. @@ -32,7 +32,7 @@ export class BadRequestException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param descriptionOrOptions a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, From c3ced1d17e7a02ca2aa98a01bb7c02805e12c088 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:19:49 -0300 Subject: [PATCH 18/38] feat(common): add error cause option add error cause option to ForbiddenException. --- packages/common/exceptions/forbidden.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/forbidden.exception.ts b/packages/common/exceptions/forbidden.exception.ts index 2c10e7a2aa9..8079823d867 100644 --- a/packages/common/exceptions/forbidden.exception.ts +++ b/packages/common/exceptions/forbidden.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Forbidden* type errors. @@ -18,7 +18,7 @@ export class ForbiddenException extends HttpException { * @usageNotes * The HTTP response status code will be 403. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 403. @@ -31,12 +31,15 @@ export class ForbiddenException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Forbidden', + descriptionOrOptions: string | HttpExceptionOptions = 'Forbidden', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class ForbiddenException extends HttpException { HttpStatus.FORBIDDEN, ), HttpStatus.FORBIDDEN, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index f05612a7f97..08e32484681 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -3,6 +3,7 @@ import { BadGatewayException, BadRequestException, ConflictException, + ForbiddenException, HttpException, NotFoundException, } from '../../exceptions'; @@ -181,6 +182,7 @@ describe('HttpException', () => { BadGatewayException, BadRequestException, ConflictException, + ForbiddenException, ]; builInErrorClasses.forEach(ExceptionClass => { From f629dc1d71545ed14daeafb1ff41822b2ffb2397 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:47:37 -0300 Subject: [PATCH 19/38] feat(common): add error cause option add error cause option to GatewayTimeoutException. --- .../common/exceptions/gateway-timeout.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/gateway-timeout.exception.ts b/packages/common/exceptions/gateway-timeout.exception.ts index e2d06851884..6953f0cb231 100644 --- a/packages/common/exceptions/gateway-timeout.exception.ts +++ b/packages/common/exceptions/gateway-timeout.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Gateway Timeout* type errors. @@ -18,7 +18,7 @@ export class GatewayTimeoutException extends HttpException { * @usageNotes * The HTTP response status code will be 504. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 504. @@ -31,12 +31,15 @@ export class GatewayTimeoutException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Gateway Timeout', + descriptionOrOptions: string | HttpExceptionOptions = 'Gateway Timeout', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class GatewayTimeoutException extends HttpException { HttpStatus.GATEWAY_TIMEOUT, ), HttpStatus.GATEWAY_TIMEOUT, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 08e32484681..7618b465f4b 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -4,6 +4,7 @@ import { BadRequestException, ConflictException, ForbiddenException, + GatewayTimeoutException, HttpException, NotFoundException, } from '../../exceptions'; @@ -183,6 +184,7 @@ describe('HttpException', () => { BadRequestException, ConflictException, ForbiddenException, + GatewayTimeoutException, ]; builInErrorClasses.forEach(ExceptionClass => { From bd7daf11c5476aa78a361600a137f07f54b59059 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:51:26 -0300 Subject: [PATCH 20/38] feat(common): add error cause option add error cause option to GoneException. --- packages/common/exceptions/gone.exception.ts | 15 +++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/gone.exception.ts b/packages/common/exceptions/gone.exception.ts index f319fe558ce..3e080906ab6 100644 --- a/packages/common/exceptions/gone.exception.ts +++ b/packages/common/exceptions/gone.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Gone* type errors. @@ -18,7 +18,7 @@ export class GoneException extends HttpException { * @usageNotes * The HTTP response status code will be 410. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 410. @@ -31,12 +31,19 @@ export class GoneException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ - constructor(objectOrError?: string | object | any, description = 'Gone') { + constructor( + objectOrError?: string | object | any, + descriptionOrOptions: string | HttpExceptionOptions = 'Gone', + ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody(objectOrError, description, HttpStatus.GONE), HttpStatus.GONE, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 7618b465f4b..d481199526d 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -5,6 +5,7 @@ import { ConflictException, ForbiddenException, GatewayTimeoutException, + GoneException, HttpException, NotFoundException, } from '../../exceptions'; @@ -185,6 +186,7 @@ describe('HttpException', () => { ConflictException, ForbiddenException, GatewayTimeoutException, + GoneException, ]; builInErrorClasses.forEach(ExceptionClass => { From 0328a5c0316ca77f5151f795a3e823dcf3d4ed64 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:54:31 -0300 Subject: [PATCH 21/38] feat(common): add error cause option add error cause option to HttpVersionNotSupportedException. --- .../http-version-not-supported.exception.ts | 14 ++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 6 ++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/common/exceptions/http-version-not-supported.exception.ts b/packages/common/exceptions/http-version-not-supported.exception.ts index ded68714b8b..922d75ff08a 100644 --- a/packages/common/exceptions/http-version-not-supported.exception.ts +++ b/packages/common/exceptions/http-version-not-supported.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Http Version Not Supported* type errors. @@ -18,7 +18,7 @@ export class HttpVersionNotSupportedException extends HttpException { * @usageNotes * The HTTP response status code will be 505. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 505. @@ -31,12 +31,17 @@ export class HttpVersionNotSupportedException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'HTTP Version Not Supported', + descriptionOrOptions: + | string + | HttpExceptionOptions = 'HTTP Version Not Supported', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +49,7 @@ export class HttpVersionNotSupportedException extends HttpException { HttpStatus.HTTP_VERSION_NOT_SUPPORTED, ), HttpStatus.HTTP_VERSION_NOT_SUPPORTED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index d481199526d..70da9502de2 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -7,6 +7,7 @@ import { GatewayTimeoutException, GoneException, HttpException, + HttpVersionNotSupportedException, NotFoundException, } from '../../exceptions'; @@ -180,16 +181,17 @@ describe('HttpException', () => { }); it('configures a cause when using a bult-in exception with options', () => { - const builInErrorClasses = [ + const builtInErrorClasses = [ BadGatewayException, BadRequestException, ConflictException, ForbiddenException, GatewayTimeoutException, GoneException, + HttpVersionNotSupportedException, ]; - builInErrorClasses.forEach(ExceptionClass => { + builtInErrorClasses.forEach(ExceptionClass => { const error = new ExceptionClass(customDescription, { cause: errorCause, }); From 11d276368ace2b4c3a8da99df33fa86df37538e4 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:56:50 -0300 Subject: [PATCH 22/38] feat(common): add error cause option add error cause option to ImATeapotException. --- packages/common/exceptions/im-a-teapot.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/im-a-teapot.exception.ts b/packages/common/exceptions/im-a-teapot.exception.ts index 4b345681ea5..76c67861e23 100644 --- a/packages/common/exceptions/im-a-teapot.exception.ts +++ b/packages/common/exceptions/im-a-teapot.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *ImATeapotException* type errors. @@ -21,7 +21,7 @@ export class ImATeapotException extends HttpException { * @usageNotes * The HTTP response status code will be 418. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 418. @@ -34,12 +34,15 @@ export class ImATeapotException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = `I'm a teapot`, + descriptionOrOptions: string | HttpExceptionOptions = `I'm a teapot`, ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -47,6 +50,7 @@ export class ImATeapotException extends HttpException { HttpStatus.I_AM_A_TEAPOT, ), HttpStatus.I_AM_A_TEAPOT, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 70da9502de2..563c35ec052 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -8,6 +8,7 @@ import { GoneException, HttpException, HttpVersionNotSupportedException, + ImATeapotException, NotFoundException, } from '../../exceptions'; @@ -189,6 +190,7 @@ describe('HttpException', () => { GatewayTimeoutException, GoneException, HttpVersionNotSupportedException, + ImATeapotException, ]; builtInErrorClasses.forEach(ExceptionClass => { From b81514384b80d6e6eb4bc69342b63929ac0bddeb Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 16:58:42 -0300 Subject: [PATCH 23/38] feat(common): add error cause option add error cause option to InternalServerErrorException. --- .../exceptions/internal-server-error.exception.ts | 14 ++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/internal-server-error.exception.ts b/packages/common/exceptions/internal-server-error.exception.ts index 673a2e7a20b..c3393cf3782 100644 --- a/packages/common/exceptions/internal-server-error.exception.ts +++ b/packages/common/exceptions/internal-server-error.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Internal Server Error* type errors. @@ -18,7 +18,7 @@ export class InternalServerErrorException extends HttpException { * @usageNotes * The HTTP response status code will be 500. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 500. @@ -31,12 +31,17 @@ export class InternalServerErrorException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Internal Server Error', + descriptionOrOptions: + | string + | HttpExceptionOptions = 'Internal Server Error', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +49,7 @@ export class InternalServerErrorException extends HttpException { HttpStatus.INTERNAL_SERVER_ERROR, ), HttpStatus.INTERNAL_SERVER_ERROR, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 563c35ec052..11bad79dbc2 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -9,6 +9,7 @@ import { HttpException, HttpVersionNotSupportedException, ImATeapotException, + InternalServerErrorException, NotFoundException, } from '../../exceptions'; @@ -191,6 +192,7 @@ describe('HttpException', () => { GoneException, HttpVersionNotSupportedException, ImATeapotException, + InternalServerErrorException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 789e99cb3bb68b6cccf18c436adcc513c9caa0c4 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:00:15 -0300 Subject: [PATCH 24/38] feat(common): add error cause option add error cause option to MethodNotAllowedException. --- .../exceptions/method-not-allowed.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/method-not-allowed.exception.ts b/packages/common/exceptions/method-not-allowed.exception.ts index f44ad305bd5..9cf0d838140 100644 --- a/packages/common/exceptions/method-not-allowed.exception.ts +++ b/packages/common/exceptions/method-not-allowed.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Method Not Allowed* type errors. @@ -18,7 +18,7 @@ export class MethodNotAllowedException extends HttpException { * @usageNotes * The HTTP response status code will be 405. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 405. @@ -31,12 +31,15 @@ export class MethodNotAllowedException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Method Not Allowed', + descriptionOrOptions: string | HttpExceptionOptions = 'Method Not Allowed', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class MethodNotAllowedException extends HttpException { HttpStatus.METHOD_NOT_ALLOWED, ), HttpStatus.METHOD_NOT_ALLOWED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 11bad79dbc2..29f2cde7454 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -10,6 +10,7 @@ import { HttpVersionNotSupportedException, ImATeapotException, InternalServerErrorException, + MethodNotAllowedException, NotFoundException, } from '../../exceptions'; @@ -193,6 +194,7 @@ describe('HttpException', () => { HttpVersionNotSupportedException, ImATeapotException, InternalServerErrorException, + MethodNotAllowedException, ]; builtInErrorClasses.forEach(ExceptionClass => { From cd44ff36960b914fcc902fc083313839bbcbb1d7 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:02:06 -0300 Subject: [PATCH 25/38] feat(common): add error cause option add error cause option to MisdirectedException. --- packages/common/exceptions/misdirected.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/misdirected.exception.ts b/packages/common/exceptions/misdirected.exception.ts index 5fa2f082c26..547ab443160 100644 --- a/packages/common/exceptions/misdirected.exception.ts +++ b/packages/common/exceptions/misdirected.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Misdirected* type errors. @@ -18,7 +18,7 @@ export class MisdirectedException extends HttpException { * @usageNotes * The HTTP response status code will be 421. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 421. @@ -31,12 +31,15 @@ export class MisdirectedException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Misdirected', + descriptionOrOptions: string | HttpExceptionOptions = 'Misdirected', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class MisdirectedException extends HttpException { HttpStatus.MISDIRECTED, ), HttpStatus.MISDIRECTED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 29f2cde7454..666f4989025 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -11,6 +11,7 @@ import { ImATeapotException, InternalServerErrorException, MethodNotAllowedException, + MisdirectedException, NotFoundException, } from '../../exceptions'; @@ -195,6 +196,7 @@ describe('HttpException', () => { ImATeapotException, InternalServerErrorException, MethodNotAllowedException, + MisdirectedException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 3a10258bc41e57afdb6da6af907bcd29dc9490e5 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:03:37 -0300 Subject: [PATCH 26/38] feat(common): add error cause option add error cause option to NotAcceptableException. --- .../exceptions/not-acceptable.exception.ts | 20 +++++++++---------- .../test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/common/exceptions/not-acceptable.exception.ts b/packages/common/exceptions/not-acceptable.exception.ts index 18e71156ce3..99c58aff24d 100644 --- a/packages/common/exceptions/not-acceptable.exception.ts +++ b/packages/common/exceptions/not-acceptable.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Not Acceptable* type errors. @@ -18,7 +18,7 @@ export class NotAcceptableException extends HttpException { * @usageNotes * The HTTP response status code will be 406. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 406. @@ -31,19 +31,19 @@ export class NotAcceptableException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Not Acceptable', + descriptionOrOptions: string | HttpExceptionOptions = 'Not Acceptable', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( - HttpException.createBody( - objectOrError, - description, - HttpStatus.NOT_ACCEPTABLE, - ), - HttpStatus.NOT_ACCEPTABLE, + HttpException.createBody(objectOrError, description, HttpStatus.CONFLICT), + HttpStatus.CONFLICT, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 666f4989025..52b86f5cf3a 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -12,6 +12,7 @@ import { InternalServerErrorException, MethodNotAllowedException, MisdirectedException, + NotAcceptableException, NotFoundException, } from '../../exceptions'; @@ -197,6 +198,7 @@ describe('HttpException', () => { InternalServerErrorException, MethodNotAllowedException, MisdirectedException, + NotAcceptableException, ]; builtInErrorClasses.forEach(ExceptionClass => { From d569aaa68d8eebceaa1086ecb209e259fd07fa3c Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:06:10 -0300 Subject: [PATCH 27/38] feat(common): add error cause option add error cause option to NotFoundException. --- packages/common/exceptions/not-found.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/not-found.exception.ts b/packages/common/exceptions/not-found.exception.ts index a8ab1491a6e..b44a744e0ec 100644 --- a/packages/common/exceptions/not-found.exception.ts +++ b/packages/common/exceptions/not-found.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Not Found* type errors. @@ -18,7 +18,7 @@ export class NotFoundException extends HttpException { * @usageNotes * The HTTP response status code will be 404. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 404. @@ -31,12 +31,15 @@ export class NotFoundException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Not Found', + descriptionOrOptions: string | HttpExceptionOptions = 'Not Found', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class NotFoundException extends HttpException { HttpStatus.NOT_FOUND, ), HttpStatus.NOT_FOUND, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 52b86f5cf3a..961f680bdb8 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -199,6 +199,7 @@ describe('HttpException', () => { MethodNotAllowedException, MisdirectedException, NotAcceptableException, + NotFoundException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 2416df695a8c711cd8282b96725264ff634d3dd7 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:07:33 -0300 Subject: [PATCH 28/38] feat(common): add error cause option add error cause option to NotImplementedException. --- .../common/exceptions/not-implemented.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/not-implemented.exception.ts b/packages/common/exceptions/not-implemented.exception.ts index 0576406fcf3..6f691264955 100644 --- a/packages/common/exceptions/not-implemented.exception.ts +++ b/packages/common/exceptions/not-implemented.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Not Implemented* type errors. @@ -18,7 +18,7 @@ export class NotImplementedException extends HttpException { * @usageNotes * The HTTP response status code will be 501. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 501. @@ -30,13 +30,16 @@ export class NotImplementedException extends HttpException { * entire JSON response body, pass an object instead. Nest will serialize the object * and return it as the JSON response body. * - * @param description string or object describing the error condition. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause * @param error a short description of the HTTP error. */ constructor( objectOrError?: string | object | any, - description = 'Not Implemented', + descriptionOrOptions: string | HttpExceptionOptions = 'Not Implemented', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class NotImplementedException extends HttpException { HttpStatus.NOT_IMPLEMENTED, ), HttpStatus.NOT_IMPLEMENTED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 961f680bdb8..6e23b385818 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -14,6 +14,7 @@ import { MisdirectedException, NotAcceptableException, NotFoundException, + NotImplementedException, } from '../../exceptions'; describe('HttpException', () => { @@ -200,6 +201,7 @@ describe('HttpException', () => { MisdirectedException, NotAcceptableException, NotFoundException, + NotImplementedException, ]; builtInErrorClasses.forEach(ExceptionClass => { From dfc28fcd2812459c281332a5eae1f3f4278f12a0 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:08:47 -0300 Subject: [PATCH 29/38] feat(common): add error cause option add error cause option to PayloadTooLargeException. --- .../common/exceptions/payload-too-large.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/payload-too-large.exception.ts b/packages/common/exceptions/payload-too-large.exception.ts index 3f967f8340a..73de7d1f2ac 100644 --- a/packages/common/exceptions/payload-too-large.exception.ts +++ b/packages/common/exceptions/payload-too-large.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Payload Too Large* type errors. @@ -18,7 +18,7 @@ export class PayloadTooLargeException extends HttpException { * @usageNotes * The HTTP response status code will be 413. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 413. @@ -31,12 +31,15 @@ export class PayloadTooLargeException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Payload Too Large', + descriptionOrOptions: string | HttpExceptionOptions = 'Payload Too Large', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class PayloadTooLargeException extends HttpException { HttpStatus.PAYLOAD_TOO_LARGE, ), HttpStatus.PAYLOAD_TOO_LARGE, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 6e23b385818..f18979b3bb0 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -15,6 +15,7 @@ import { NotAcceptableException, NotFoundException, NotImplementedException, + PayloadTooLargeException, } from '../../exceptions'; describe('HttpException', () => { @@ -202,6 +203,7 @@ describe('HttpException', () => { NotAcceptableException, NotFoundException, NotImplementedException, + PayloadTooLargeException, ]; builtInErrorClasses.forEach(ExceptionClass => { From d40ebd17bfe5371d41067a013a1b193cc1a5418b Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:11:25 -0300 Subject: [PATCH 30/38] feat(common): add error cause option add error cause option to PreconditionFailedException. --- .../exceptions/precondition-failed.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/precondition-failed.exception.ts b/packages/common/exceptions/precondition-failed.exception.ts index 6e84563963a..d03da41d057 100644 --- a/packages/common/exceptions/precondition-failed.exception.ts +++ b/packages/common/exceptions/precondition-failed.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Precondition Failed* type errors. @@ -18,7 +18,7 @@ export class PreconditionFailedException extends HttpException { * @usageNotes * The HTTP response status code will be 412. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 412. @@ -31,12 +31,15 @@ export class PreconditionFailedException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Precondition Failed', + descriptionOrOptions: string | HttpExceptionOptions = 'Precondition Failed', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class PreconditionFailedException extends HttpException { HttpStatus.PRECONDITION_FAILED, ), HttpStatus.PRECONDITION_FAILED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index f18979b3bb0..4a2d78e006e 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -16,6 +16,7 @@ import { NotFoundException, NotImplementedException, PayloadTooLargeException, + PreconditionFailedException, } from '../../exceptions'; describe('HttpException', () => { @@ -204,6 +205,7 @@ describe('HttpException', () => { NotFoundException, NotImplementedException, PayloadTooLargeException, + PreconditionFailedException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 5031f4105f5f8abdb86aaea22096b109fb2a3eb2 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:15:04 -0300 Subject: [PATCH 31/38] feat(common): add error cause option add error cause option to RequestTimeoutException. --- .../common/exceptions/request-timeout.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/request-timeout.exception.ts b/packages/common/exceptions/request-timeout.exception.ts index 8521e290f76..d91c3cfd1bb 100644 --- a/packages/common/exceptions/request-timeout.exception.ts +++ b/packages/common/exceptions/request-timeout.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Request Timeout* type errors. @@ -18,7 +18,7 @@ export class RequestTimeoutException extends HttpException { * @usageNotes * The HTTP response status code will be 408. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 408. @@ -31,12 +31,15 @@ export class RequestTimeoutException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Request Timeout', + descriptionOrOptions: string | HttpExceptionOptions = 'Request Timeout', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class RequestTimeoutException extends HttpException { HttpStatus.REQUEST_TIMEOUT, ), HttpStatus.REQUEST_TIMEOUT, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 4a2d78e006e..c8b6bf9d3f0 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -17,6 +17,7 @@ import { NotImplementedException, PayloadTooLargeException, PreconditionFailedException, + RequestTimeoutException, } from '../../exceptions'; describe('HttpException', () => { @@ -206,6 +207,7 @@ describe('HttpException', () => { NotImplementedException, PayloadTooLargeException, PreconditionFailedException, + RequestTimeoutException, ]; builtInErrorClasses.forEach(ExceptionClass => { From e8abd9af20929b28bcdd1acf9e80b063102b1041 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:16:21 -0300 Subject: [PATCH 32/38] feat(common): add error cause option add error cause option to ServiceUnavailableException. --- .../exceptions/service-unavailable.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/service-unavailable.exception.ts b/packages/common/exceptions/service-unavailable.exception.ts index b7721322f46..2d1c6bd0367 100644 --- a/packages/common/exceptions/service-unavailable.exception.ts +++ b/packages/common/exceptions/service-unavailable.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Service Unavailable* type errors. @@ -18,7 +18,7 @@ export class ServiceUnavailableException extends HttpException { * @usageNotes * The HTTP response status code will be 503. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 503. @@ -31,12 +31,15 @@ export class ServiceUnavailableException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Service Unavailable', + descriptionOrOptions: string | HttpExceptionOptions = 'Service Unavailable', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class ServiceUnavailableException extends HttpException { HttpStatus.SERVICE_UNAVAILABLE, ), HttpStatus.SERVICE_UNAVAILABLE, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index c8b6bf9d3f0..bd62924fda4 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -18,6 +18,7 @@ import { PayloadTooLargeException, PreconditionFailedException, RequestTimeoutException, + ServiceUnavailableException, } from '../../exceptions'; describe('HttpException', () => { @@ -208,6 +209,7 @@ describe('HttpException', () => { PayloadTooLargeException, PreconditionFailedException, RequestTimeoutException, + ServiceUnavailableException, ]; builtInErrorClasses.forEach(ExceptionClass => { From f62acac81534e9d5c7f48931cabbcf34022abf68 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:17:26 -0300 Subject: [PATCH 33/38] feat(common): add error cause option add error cause option to UnauthorizedException. --- packages/common/exceptions/unauthorized.exception.ts | 12 ++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/unauthorized.exception.ts b/packages/common/exceptions/unauthorized.exception.ts index 1791316c6e9..b85fa847e33 100644 --- a/packages/common/exceptions/unauthorized.exception.ts +++ b/packages/common/exceptions/unauthorized.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Unauthorized* type errors. @@ -18,7 +18,7 @@ export class UnauthorizedException extends HttpException { * @usageNotes * The HTTP response status code will be 401. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 401. @@ -31,12 +31,15 @@ export class UnauthorizedException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Unauthorized', + descriptionOrOptions: string | HttpExceptionOptions = 'Unauthorized', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +47,7 @@ export class UnauthorizedException extends HttpException { HttpStatus.UNAUTHORIZED, ), HttpStatus.UNAUTHORIZED, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index bd62924fda4..87bbd38f336 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -19,6 +19,7 @@ import { PreconditionFailedException, RequestTimeoutException, ServiceUnavailableException, + UnauthorizedException, } from '../../exceptions'; describe('HttpException', () => { @@ -210,6 +211,7 @@ describe('HttpException', () => { PreconditionFailedException, RequestTimeoutException, ServiceUnavailableException, + UnauthorizedException, ]; builtInErrorClasses.forEach(ExceptionClass => { From b4aca5d01facba08fceeea657454f9c92dbb7269 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:18:54 -0300 Subject: [PATCH 34/38] feat(common): add error cause option add error cause option to UnprocessableEntityException. --- .../exceptions/unprocessable-entity.exception.ts | 14 ++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/unprocessable-entity.exception.ts b/packages/common/exceptions/unprocessable-entity.exception.ts index b1cf34b77a9..a4e012cacf0 100644 --- a/packages/common/exceptions/unprocessable-entity.exception.ts +++ b/packages/common/exceptions/unprocessable-entity.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Unprocessable Entity* type errors. @@ -18,7 +18,7 @@ export class UnprocessableEntityException extends HttpException { * @usageNotes * The HTTP response status code will be 422. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 422. @@ -31,12 +31,17 @@ export class UnprocessableEntityException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Unprocessable Entity', + descriptionOrOptions: + | string + | HttpExceptionOptions = 'Unprocessable Entity', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +49,7 @@ export class UnprocessableEntityException extends HttpException { HttpStatus.UNPROCESSABLE_ENTITY, ), HttpStatus.UNPROCESSABLE_ENTITY, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 87bbd38f336..2313c81c5d5 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -20,6 +20,7 @@ import { RequestTimeoutException, ServiceUnavailableException, UnauthorizedException, + UnprocessableEntityException, } from '../../exceptions'; describe('HttpException', () => { @@ -212,6 +213,7 @@ describe('HttpException', () => { RequestTimeoutException, ServiceUnavailableException, UnauthorizedException, + UnprocessableEntityException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 379b82c189a13c437417e577807c061a42a8da40 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:20:03 -0300 Subject: [PATCH 35/38] feat(common): add error cause option add error cause option to UnsupportedMediaTypeException. --- .../exceptions/unsupported-media-type.exception.ts | 14 ++++++++++---- .../common/test/exceptions/http.exception.spec.ts | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/common/exceptions/unsupported-media-type.exception.ts b/packages/common/exceptions/unsupported-media-type.exception.ts index eaeab69a9ca..fb8a0e1df44 100644 --- a/packages/common/exceptions/unsupported-media-type.exception.ts +++ b/packages/common/exceptions/unsupported-media-type.exception.ts @@ -1,5 +1,5 @@ import { HttpStatus } from '../enums/http-status.enum'; -import { HttpException } from './http.exception'; +import { HttpException, HttpExceptionOptions } from './http.exception'; /** * Defines an HTTP exception for *Unsupported Media Type* type errors. @@ -18,7 +18,7 @@ export class UnsupportedMediaTypeException extends HttpException { * @usageNotes * The HTTP response status code will be 415. * - The `objectOrError` argument defines the JSON response body or the message string. - * - The `description` argument contains a short description of the HTTP error. + * - The `descriptionOrOptions` argument contains either a short description of the HTTP error or an options object used to provide an underlying error cause. * * By default, the JSON response body contains two properties: * - `statusCode`: this will be the value 415. @@ -31,12 +31,17 @@ export class UnsupportedMediaTypeException extends HttpException { * and return it as the JSON response body. * * @param objectOrError string or object describing the error condition. - * @param description a short description of the HTTP error. + * @param descriptionOrOptions either a short description of the HTTP error or an options object used to provide an underlying error cause */ constructor( objectOrError?: string | object | any, - description = 'Unsupported Media Type', + descriptionOrOptions: + | string + | HttpExceptionOptions = 'Unsupported Media Type', ) { + const { description, httpExceptionOptions } = + HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); + super( HttpException.createBody( objectOrError, @@ -44,6 +49,7 @@ export class UnsupportedMediaTypeException extends HttpException { HttpStatus.UNSUPPORTED_MEDIA_TYPE, ), HttpStatus.UNSUPPORTED_MEDIA_TYPE, + httpExceptionOptions, ); } } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 2313c81c5d5..9bdd11a3eeb 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -21,6 +21,7 @@ import { ServiceUnavailableException, UnauthorizedException, UnprocessableEntityException, + UnsupportedMediaTypeException, } from '../../exceptions'; describe('HttpException', () => { @@ -214,6 +215,7 @@ describe('HttpException', () => { ServiceUnavailableException, UnauthorizedException, UnprocessableEntityException, + UnsupportedMediaTypeException, ]; builtInErrorClasses.forEach(ExceptionClass => { From 971ce5f56fac4fe87ad9f6b85306d5e3ff9b5bb8 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:21:13 -0300 Subject: [PATCH 36/38] test(common): reuse error cause variable reuse errorCause variable in HttpException test --- packages/common/test/exceptions/http.exception.spec.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 9bdd11a3eeb..bc7c611fac9 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -180,17 +180,14 @@ describe('HttpException', () => { }); it('configures a cause when message is a string and the options object is passed', () => { - const causeError = new Error('Some Error'); - - const customDescription = 'custom description'; const error = new HttpException(customDescription, 400, { - cause: causeError, + cause: errorCause, }); expect(`${error}`).to.be.eql(`HttpException: ${customDescription}`); const { cause } = error; - expect(cause).to.be.eql(causeError); + expect(cause).to.be.eql(errorCause); }); it('configures a cause when using a bult-in exception with options', () => { From 45b6cc10474d277795bec887ace3b334d66a4665 Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:37:27 -0300 Subject: [PATCH 37/38] test(common): add http exception tests add tests for all HttpException children classes and fix NotAcceptableException wrong status code. --- .../exceptions/not-acceptable.exception.ts | 8 +++- .../test/exceptions/http.exception.spec.ts | 41 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/common/exceptions/not-acceptable.exception.ts b/packages/common/exceptions/not-acceptable.exception.ts index 99c58aff24d..548b2dd7916 100644 --- a/packages/common/exceptions/not-acceptable.exception.ts +++ b/packages/common/exceptions/not-acceptable.exception.ts @@ -41,8 +41,12 @@ export class NotAcceptableException extends HttpException { HttpException.extractDescriptionAndOptionsFrom(descriptionOrOptions); super( - HttpException.createBody(objectOrError, description, HttpStatus.CONFLICT), - HttpStatus.CONFLICT, + HttpException.createBody( + objectOrError, + description, + HttpStatus.NOT_ACCEPTABLE, + ), + HttpStatus.NOT_ACCEPTABLE, httpExceptionOptions, ); } diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index bc7c611fac9..5e9553e2f6c 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -1,3 +1,4 @@ +import { Type } from '../../../common'; import { expect } from 'chai'; import { BadGatewayException, @@ -69,14 +70,38 @@ describe('HttpException', () => { describe('getResponse', () => { it('should return a response with default message and status code', () => { - expect(new BadRequestException().getResponse()).to.be.eql({ - message: 'Bad Request', - statusCode: 400, - }); - expect(new NotFoundException().getResponse()).to.be.eql({ - message: 'Not Found', - statusCode: 404, - }); + const testCases: [Type, number, string][] = [ + [BadRequestException, 400, 'Bad Request'], + [UnauthorizedException, 401, 'Unauthorized'], + [ForbiddenException, 403, 'Forbidden'], + [NotFoundException, 404, 'Not Found'], + [MethodNotAllowedException, 405, 'Method Not Allowed'], + [NotAcceptableException, 406, 'Not Acceptable'], + [RequestTimeoutException, 408, 'Request Timeout'], + [ConflictException, 409, 'Conflict'], + [GoneException, 410, 'Gone'], + [PreconditionFailedException, 412, 'Precondition Failed'], + [PayloadTooLargeException, 413, 'Payload Too Large'], + [UnsupportedMediaTypeException, 415, 'Unsupported Media Type'], + [ImATeapotException, 418, "I'm a teapot"], + [MisdirectedException, 421, 'Misdirected'], + [UnprocessableEntityException, 422, 'Unprocessable Entity'], + [InternalServerErrorException, 500, 'Internal Server Error'], + [NotImplementedException, 501, 'Not Implemented'], + [BadGatewayException, 502, 'Bad Gateway'], + [ServiceUnavailableException, 503, 'Service Unavailable'], + [GatewayTimeoutException, 504, 'Gateway Timeout'], + [HttpVersionNotSupportedException, 505, 'HTTP Version Not Supported'], + ]; + + testCases.forEach( + ([ExceptionClass, expectedStatus, expectedMessage]) => { + expect(new ExceptionClass().getResponse()).to.be.eql({ + message: expectedMessage, + statusCode: expectedStatus, + }); + }, + ); }); it('should return a response with an "error" attribute when description was provided as the "option" object', () => { From ab881e3b635c2b6978e4671d7bd2b4fdf275fb0c Mon Sep 17 00:00:00 2001 From: Thiago Martins Date: Thu, 27 Oct 2022 17:40:41 -0300 Subject: [PATCH 38/38] test(common): add http exception tests add "getStatus" tests for all HttpException children classes --- .../test/exceptions/http.exception.spec.ts | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/common/test/exceptions/http.exception.spec.ts b/packages/common/test/exceptions/http.exception.spec.ts index 5e9553e2f6c..0b7f21ed7fa 100644 --- a/packages/common/test/exceptions/http.exception.spec.ts +++ b/packages/common/test/exceptions/http.exception.spec.ts @@ -63,8 +63,33 @@ describe('HttpException', () => { describe('built-in exceptions', () => { describe('getStatus', () => { it('should return given status code', () => { - expect(new BadRequestException().getStatus()).to.be.eql(400); - expect(new NotFoundException().getStatus()).to.be.eql(404); + const testCases: [Type, number][] = [ + [BadRequestException, 400], + [UnauthorizedException, 401], + [ForbiddenException, 403], + [NotFoundException, 404], + [MethodNotAllowedException, 405], + [NotAcceptableException, 406], + [RequestTimeoutException, 408], + [ConflictException, 409], + [GoneException, 410], + [PreconditionFailedException, 412], + [PayloadTooLargeException, 413], + [UnsupportedMediaTypeException, 415], + [ImATeapotException, 418], + [MisdirectedException, 421], + [UnprocessableEntityException, 422], + [InternalServerErrorException, 500], + [NotImplementedException, 501], + [BadGatewayException, 502], + [ServiceUnavailableException, 503], + [GatewayTimeoutException, 504], + [HttpVersionNotSupportedException, 505], + ]; + + testCases.forEach(([ExceptionClass, expectedStatus]) => { + expect(new ExceptionClass().getStatus()).to.be.eql(expectedStatus); + }); }); });