From b9295f00c292139a5e72b7c2203afc054bed80aa Mon Sep 17 00:00:00 2001 From: Ruben Verborgh Date: Wed, 14 Jul 2021 15:17:58 +0100 Subject: [PATCH] feat: Default error code to HTTP status code. --- .../conversion/ErrorToTemplateConverter.ts | 2 +- src/util/errors/HttpError.ts | 4 ++-- .../conversion/ErrorToTemplateConverter.test.ts | 17 ++++++++++++++++- test/unit/util/errors/HttpError.test.ts | 4 ++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/storage/conversion/ErrorToTemplateConverter.ts b/src/storage/conversion/ErrorToTemplateConverter.ts index b78bd585c..083678756 100644 --- a/src/storage/conversion/ErrorToTemplateConverter.ts +++ b/src/storage/conversion/ErrorToTemplateConverter.ts @@ -57,7 +57,7 @@ export class ErrorToTemplateConverter extends TypedRepresentationConverter { } private async getErrorCodeMessage(error: Error): Promise { - if (HttpError.isInstance(error) && error.errorCode) { + if (HttpError.isInstance(error)) { let template: string; try { const fileName = `${error.errorCode}${this.extension}`; diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index 022b98309..09ad058a5 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -14,7 +14,7 @@ export class HttpError extends Error implements HttpErrorOptions { protected static readonly statusCode: number; public readonly statusCode: number; public readonly cause?: unknown; - public readonly errorCode?: string; + public readonly errorCode: string; public readonly details?: NodeJS.Dict; /** @@ -29,7 +29,7 @@ export class HttpError extends Error implements HttpErrorOptions { this.statusCode = statusCode; this.name = name; this.cause = options.cause; - this.errorCode = options.errorCode; + this.errorCode = options.errorCode ?? `H${statusCode}`; this.details = options.details; } diff --git a/test/unit/storage/conversion/ErrorToTemplateConverter.test.ts b/test/unit/storage/conversion/ErrorToTemplateConverter.test.ts index 7fc33ca50..d1502d360 100644 --- a/test/unit/storage/conversion/ErrorToTemplateConverter.test.ts +++ b/test/unit/storage/conversion/ErrorToTemplateConverter.test.ts @@ -41,7 +41,22 @@ describe('An ErrorToTemplateConverter', (): void => { await expect(prom).rejects.toThrow(InternalServerError); }); - it('calls the template engine with all error fields.', async(): Promise => { + it('works with non-HTTP errors.', async(): Promise => { + const error = new Error('error text'); + const representation = new BasicRepresentation([ error ], 'internal/error', false); + const prom = converter.handle({ identifier, representation, preferences }); + await expect(prom).resolves.toBeDefined(); + const result = await prom; + expect(result.binary).toBe(true); + expect(result.metadata.contentType).toBe('text/html'); + await expect(readableToString(result.data)).resolves.toBe(''); + expect(engine.apply).toHaveBeenCalledTimes(1); + expect(engine.apply).toHaveBeenLastCalledWith( + '{{ template }}', { name: 'Error', message: 'error text', stack: error.stack }, + ); + }); + + it('calls the template engine with all HTTP error fields.', async(): Promise => { const error = new BadRequestHttpError('error text'); const representation = new BasicRepresentation([ error ], 'internal/error', false); const prom = converter.handle({ identifier, representation, preferences }); diff --git a/test/unit/util/errors/HttpError.test.ts b/test/unit/util/errors/HttpError.test.ts index bccf5b493..e263e849a 100644 --- a/test/unit/util/errors/HttpError.test.ts +++ b/test/unit/util/errors/HttpError.test.ts @@ -63,6 +63,10 @@ describe('HttpError', (): void => { expect(instance.errorCode).toBe(options.errorCode); }); + it('defaults to an HTTP-specific error code.', (): void => { + expect(new constructor().errorCode).toBe(`H${statusCode}`); + }); + it('sets the details.', (): void => { expect(instance.details).toBe(options.details); });