import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation'; import { ErrorToJsonConverter } from '../../../../src/storage/conversion/ErrorToJsonConverter'; import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { readJsonStream } from '../../../../src/util/StreamUtil'; describe('An ErrorToJsonConverter', (): void => { const identifier = { path: 'http://test.com/error' }; const converter = new ErrorToJsonConverter(); const preferences = {}; it('supports going from errors to json.', async(): Promise => { await expect(converter.getOutputTypes('internal/error')).resolves.toEqual({ 'application/json': 1 }); }); it('adds all HttpError fields.', async(): Promise => { const error = new BadRequestHttpError('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('application/json'); await expect(readJsonStream(result.data)).resolves.toEqual({ name: 'BadRequestHttpError', message: 'error text', statusCode: 400, errorCode: 'H400', stack: error.stack, }); }); it('copies the HttpError details.', async(): Promise => { const error = new BadRequestHttpError('error text', { details: { important: 'detail' }}); 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('application/json'); await expect(readJsonStream(result.data)).resolves.toEqual({ name: 'BadRequestHttpError', message: 'error text', statusCode: 400, errorCode: 'H400', details: { important: 'detail' }, stack: error.stack, }); }); it('does not copy the details if they are not serializable.', async(): Promise => { const error = new BadRequestHttpError('error text', { details: { object: BigInt(1) }}); 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('application/json'); await expect(readJsonStream(result.data)).resolves.toEqual({ name: 'BadRequestHttpError', message: 'error text', statusCode: 400, errorCode: 'H400', stack: error.stack, }); }); it('defaults to status code 500 for 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('application/json'); await expect(readJsonStream(result.data)).resolves.toEqual({ name: 'Error', message: 'error text', statusCode: 500, stack: error.stack, }); }); it('only adds stack if it is defined.', async(): Promise => { const error = new Error('error text'); delete error.stack; 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('application/json'); await expect(readJsonStream(result.data)).resolves.toEqual({ name: 'Error', message: 'error text', statusCode: 500, }); }); });