Even denser errors

This commit is contained in:
Fredrik Adelöw
2020-05-04 16:34:17 +02:00
parent e5529c249b
commit 129991fcfd
4 changed files with 29 additions and 49 deletions
+20 -40
View File
@@ -28,51 +28,39 @@
class CustomErrorBase extends Error {
readonly cause?: Error;
constructor(constructor: Function, message?: string, cause?: Error) {
super(message);
Object.setPrototypeOf(this, constructor.prototype);
Error.captureStackTrace(this, constructor);
this.name = this.constructor.name;
this.cause = cause;
}
toString() {
let result = super.toString();
if (this.cause) {
result += `; caused by ${this.cause.toString()}`;
constructor(message?: string, cause?: Error) {
let fullMessage = message;
if (cause) {
if (fullMessage) {
fullMessage += `; caused by ${cause}`;
} else {
fullMessage = `caused by ${cause}`;
}
}
return result;
super(fullMessage);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.cause = cause;
}
}
/**
* The request is malformed and cannot be processed.
*/
export class BadRequestError extends CustomErrorBase {
constructor(message?: string, cause?: Error) {
super(BadRequestError, message, cause);
}
}
export class BadRequestError extends CustomErrorBase {}
/**
* The request requires authentication, which was not properly supplied.
*/
export class UnauthenticatedError extends CustomErrorBase {
constructor(message?: string, cause?: Error) {
super(UnauthenticatedError, message, cause);
}
}
export class AuthenticationError extends CustomErrorBase {}
/**
* The authenticated caller is not permitted to perform this request.
* The authenticated caller is not allowed to perform this request.
*/
export class ForbiddenError extends CustomErrorBase {
constructor(message?: string, cause?: Error) {
super(ForbiddenError, message, cause);
}
}
export class NotAllowedError extends CustomErrorBase {}
/**
* The requested resource could not be found.
@@ -80,18 +68,10 @@ export class ForbiddenError extends CustomErrorBase {
* Note that this error usually is used to indicate that an entity with a given
* ID does not exist, rather than signalling that an entire route is missing.
*/
export class NotFoundError extends CustomErrorBase {
constructor(message?: string, cause?: Error) {
super(NotFoundError, message, cause);
}
}
export class NotFoundError extends CustomErrorBase {}
/**
* The request could not complete due to a conflict in the current state of the
* resource.
*/
export class ConflictError extends CustomErrorBase {
constructor(message?: string, cause?: Error) {
super(ConflictError, message, cause);
}
}
export class ConflictError extends CustomErrorBase {}
@@ -52,11 +52,11 @@ describe('errorHandler', () => {
app.use('/BadRequestError', () => {
throw new errors.BadRequestError();
});
app.use('/UnauthenticatedError', () => {
throw new errors.UnauthenticatedError();
app.use('/AuthenticationError', () => {
throw new errors.AuthenticationError();
});
app.use('/ForbiddenError', () => {
throw new errors.ForbiddenError();
app.use('/NotAllowedError', () => {
throw new errors.NotAllowedError();
});
app.use('/NotFoundError', () => {
throw new errors.NotFoundError();
@@ -68,8 +68,8 @@ describe('errorHandler', () => {
const r = request(app);
expect((await r.get('/BadRequestError')).status).toBe(400);
expect((await r.get('/UnauthenticatedError')).status).toBe(401);
expect((await r.get('/ForbiddenError')).status).toBe(403);
expect((await r.get('/AuthenticationError')).status).toBe(401);
expect((await r.get('/NotAllowedError')).status).toBe(403);
expect((await r.get('/NotFoundError')).status).toBe(404);
expect((await r.get('/ConflictError')).status).toBe(409);
});
@@ -81,9 +81,9 @@ function getStatusCode(error: Error): number {
switch (error.name) {
case errors.BadRequestError.name:
return 400;
case errors.UnauthenticatedError.name:
case errors.AuthenticationError.name:
return 401;
case errors.ForbiddenError.name:
case errors.NotAllowedError.name:
return 403;
case errors.NotFoundError.name:
return 404;
+1 -1
View File
@@ -7,7 +7,7 @@
"sourceMap": true,
"declaration": true,
"strict": true,
"target": "es5",
"target": "ES2019",
"module": "commonjs",
"esModuleInterop": true,
"types": ["node", "jest"]