Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,30 @@ There are set of prepared errors you can use:
* NotFoundError
* UnauthorizedError

You can also create and use your own errors by extending `HttpError` class.

You can also create and use your own errors by extending `HttpError` class.
To define the data returned to the client, you could define a toJSON method in your error.

```typescript
class DbError extends HttpError {
public operationName: string;
public args: any[];

constructor(operationName: string, args: any[] = []) {
super(500);
Object.setPrototypeOf(this, DbError.prototype);
this.operationName = operationName;
this.args = args; // can be used for internal logging
}

toJSON() {
return {
status: this.httpCode,
failedOperation: this.operationName
}
}
}
```

#### Enable CORS

Expand Down
3 changes: 3 additions & 0 deletions src/driver/BaseDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ export abstract class BaseDriver {
if (!this.isDefaultErrorHandlingEnabled)
return error;

if (typeof error.toJSON === "function")
return error.toJSON();

let processedError: any = {};
if (error instanceof Error) {
const name = error.name && error.name !== "Error" ? error.name : error.constructor.name;
Expand Down
36 changes: 36 additions & 0 deletions test/functional/express-error-handling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Middleware} from "../../src/decorator/Middleware";
import {UseAfter} from "../../src/decorator/UseAfter";
import {ExpressErrorMiddlewareInterface} from "../../src/driver/express/ExpressErrorMiddlewareInterface";
import {NotFoundError} from "../../src/http-error/NotFoundError";
import {HttpError} from "../../src/http-error/HttpError";
const chakram = require("chakram");
const expect = chakram.expect;

Expand Down Expand Up @@ -54,6 +55,25 @@ describe("express error handling", () => {

}

class ToJsonError extends HttpError {
public publicData: string;
public secretData: string;

constructor(httpCode: number, publicMsg?: string, privateMsg?: string) {
super(httpCode);
Object.setPrototypeOf(this, ToJsonError.prototype);
this.publicData = publicMsg || "public";
this.secretData = privateMsg || "secret";
}

toJSON() {
return {
status: this.httpCode,
publicData: `${this.publicData} (${this.httpCode})`
}
}
}

@JsonController()
class ExpressErrorHandlerController {

Expand Down Expand Up @@ -97,6 +117,11 @@ describe("express error handling", () => {
return "1234";
}

@Get("/stories")
stories() {
throw new ToJsonError(503, "sorry, try it again later", "impatient user");
}

}
});

Expand Down Expand Up @@ -154,4 +179,15 @@ describe("express error handling", () => {
});
});

it("should process JsonErrors by their toJSON method if it exists", () => {
return chakram
.get("http://127.0.0.1:3001/stories")
.then((response: any) => {
expect(response).to.have.status(503);
expect(response.body).to.have.property("status").and.equals(503);
expect(response.body).to.have.property("publicData").and.equals("sorry, try it again later (503)");
expect(response.body).to.not.have.property("secretData");
});
});

});