mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Make aggregated errors prettier
This commit is contained in:
parent
4b7621f9e0
commit
0d5d072f79
@ -16,14 +16,23 @@ export function getStatusCode(error: Error): number {
|
|||||||
* If they are all within the 4xx range, 400 will be used, otherwise 500.
|
* If they are all within the 4xx range, 400 will be used, otherwise 500.
|
||||||
*
|
*
|
||||||
* @param errors - Errors to combine.
|
* @param errors - Errors to combine.
|
||||||
* @param messagePrefix - Prefix for the aggregate error message. Will be followed with an array of all the messages.
|
|
||||||
*/
|
*/
|
||||||
export function createAggregateError(errors: Error[], messagePrefix = 'No handler supports the given input:'):
|
export function createAggregateError(errors: Error[]):
|
||||||
HttpError {
|
HttpError {
|
||||||
const httpErrors = errors.map((error): HttpError =>
|
const httpErrors = errors.map((error): HttpError =>
|
||||||
HttpError.isInstance(error) ? error : new InternalServerError(createErrorMessage(error)));
|
HttpError.isInstance(error) ? error : new InternalServerError(createErrorMessage(error)));
|
||||||
const joined = httpErrors.map((error: Error): string => error.message).join(', ');
|
const messages = httpErrors.map((error: Error): string => error.message).filter((msg): boolean => msg.length > 0);
|
||||||
const message = `${messagePrefix} [${joined}]`;
|
|
||||||
|
// Let message depend on the messages that were present.
|
||||||
|
// This prevents a bunch of empty strings being joined in the case most of them were 404s.
|
||||||
|
let message: string;
|
||||||
|
if (messages.length === 0) {
|
||||||
|
message = '';
|
||||||
|
} else if (messages.length === 1) {
|
||||||
|
message = messages[0];
|
||||||
|
} else {
|
||||||
|
message = `Multiple handler errors: ${messages.join(', ')}`;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if all errors have the same status code
|
// Check if all errors have the same status code
|
||||||
if (httpErrors.length > 0 && httpErrors.every((error): boolean => error.statusCode === httpErrors[0].statusCode)) {
|
if (httpErrors.length > 0 && httpErrors.every((error): boolean => error.statusCode === httpErrors[0].statusCode)) {
|
||||||
|
@ -3,7 +3,7 @@ import { createAggregateError, getStatusCode } from '../../../../src/util/errors
|
|||||||
import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError';
|
import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError';
|
||||||
|
|
||||||
describe('ErrorUtil', (): void => {
|
describe('ErrorUtil', (): void => {
|
||||||
describe('createAggregateError', (): void => {
|
describe('#createAggregateError', (): void => {
|
||||||
const error401 = new HttpError(401, 'UnauthorizedHttpError');
|
const error401 = new HttpError(401, 'UnauthorizedHttpError');
|
||||||
const error415 = new HttpError(415, 'UnsupportedMediaTypeHttpError');
|
const error415 = new HttpError(415, 'UnsupportedMediaTypeHttpError');
|
||||||
const error501 = new HttpError(501, 'NotImplementedHttpError');
|
const error501 = new HttpError(501, 'NotImplementedHttpError');
|
||||||
@ -36,6 +36,19 @@ describe('ErrorUtil', (): void => {
|
|||||||
name: 'InternalServerError',
|
name: 'InternalServerError',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('has no error message if none of the errors had one.', async(): Promise<void> => {
|
||||||
|
expect(createAggregateError([ error401, error501 ]).message).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('copies the error message if there is one error with a message.', async(): Promise<void> => {
|
||||||
|
expect(createAggregateError([ error, error501 ]).message).toBe('noStatusCode');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('joins the error messages if there are multiple.', async(): Promise<void> => {
|
||||||
|
expect(createAggregateError([ error, error, error501 ]).message)
|
||||||
|
.toBe('Multiple handler errors: noStatusCode, noStatusCode');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#getStatusCode', (): void => {
|
describe('#getStatusCode', (): void => {
|
||||||
|
@ -26,7 +26,7 @@ describe('A BooleanHandler', (): void => {
|
|||||||
|
|
||||||
it('errors if none of its handlers supports the input.', async(): Promise<void> => {
|
it('errors if none of its handlers supports the input.', async(): Promise<void> => {
|
||||||
const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]);
|
const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]);
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.canHandle(null)).rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns true if any of its handlers returns true.', async(): Promise<void> => {
|
it('returns true if any of its handlers returns true.', async(): Promise<void> => {
|
||||||
@ -51,6 +51,6 @@ describe('A BooleanHandler', (): void => {
|
|||||||
|
|
||||||
it('throws the canHandle error when calling handleSafe with unsupported input.', async(): Promise<void> => {
|
it('throws the canHandle error when calling handleSafe with unsupported input.', async(): Promise<void> => {
|
||||||
const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]);
|
const handler = new BooleanHandler([ handlerCanNotHandle, handlerCanNotHandle ]);
|
||||||
await expect(handler.handleSafe(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.handleSafe(null)).rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -17,12 +17,12 @@ describe('HandlerUtil', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('errors if there is no matching handler.', async(): Promise<void> => {
|
it('errors if there is no matching handler.', async(): Promise<void> => {
|
||||||
await expect(findHandler([ handlerFalse, handlerFalse ], null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(findHandler([ handlerFalse, handlerFalse ], null)).rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports non-native Errors.', async(): Promise<void> => {
|
it('supports non-native Errors.', async(): Promise<void> => {
|
||||||
handlerFalse.canHandle = jest.fn().mockRejectedValue('apple');
|
handlerFalse.canHandle = jest.fn().mockRejectedValue('apple');
|
||||||
await expect(findHandler([ handlerFalse ], null)).rejects.toThrow('[Unknown error: apple]');
|
await expect(findHandler([ handlerFalse ], null)).rejects.toThrow('Unknown error: apple');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ describe('HandlerUtil', (): void => {
|
|||||||
|
|
||||||
it('errors if there is no matching handler.', async(): Promise<void> => {
|
it('errors if there is no matching handler.', async(): Promise<void> => {
|
||||||
await expect(filterHandlers([ handlerFalse, handlerFalse ], null))
|
await expect(filterHandlers([ handlerFalse, handlerFalse ], null))
|
||||||
.rejects.toThrow('[Not supported, Not supported]');
|
.rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -42,7 +42,7 @@ describe('A WaterfallHandler', (): void => {
|
|||||||
it('can not handle data if no handler supports it.', async(): Promise<void> => {
|
it('can not handle data if no handler supports it.', async(): Promise<void> => {
|
||||||
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.canHandle(null)).rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws unknown errors if no Error objects are thrown.', async(): Promise<void> => {
|
it('throws unknown errors if no Error objects are thrown.', async(): Promise<void> => {
|
||||||
@ -51,7 +51,7 @@ describe('A WaterfallHandler', (): void => {
|
|||||||
};
|
};
|
||||||
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.canHandle(null)).rejects.toThrow('[Unknown error: apple, Unknown error: apple]');
|
await expect(handler.canHandle(null)).rejects.toThrow('Unknown error: apple, Unknown error: apple');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles data if a handler supports it.', async(): Promise<void> => {
|
it('handles data if a handler supports it.', async(): Promise<void> => {
|
||||||
@ -79,7 +79,7 @@ describe('A WaterfallHandler', (): void => {
|
|||||||
it('throws the canHandle error when calling handleSafe if the data is not supported.', async(): Promise<void> => {
|
it('throws the canHandle error when calling handleSafe if the data is not supported.', async(): Promise<void> => {
|
||||||
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
const handler = new WaterfallHandler([ handlerFalse, handlerFalse ]);
|
||||||
|
|
||||||
await expect(handler.handleSafe(null)).rejects.toThrow('[Not supported, Not supported]');
|
await expect(handler.handleSafe(null)).rejects.toThrow('Not supported, Not supported');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user