Override Global error handler

All errors are intercepted by the . By default, all HTTP Exceptions are automatically sent to the client, and technical error are sent as Internal Server Error.

Here the original :

import {Constant} from "@tsed/di";
import * as Express from "express";
import {Exception} from "ts-httpexceptions";
import {Err, IMiddlewareError, IResponseError, Middleware, Req, Res} from "../../mvc";

/**
 * @middleware
 */
@Middleware()
export class GlobalErrorHandlerMiddleware implements IMiddlewareError {
  @Constant("errors.headerName", "errors")
  protected headerName: string;

  use(@Err() error: any, @Req() request: Req, @Res() response: Res): any {
    const toHTML = (message = "") => message.replace(/\n/gi, "<br />");

    if (error instanceof Exception || error.status) {
      request.log.error({
        error: {
          message: error.message,
          stack: error.stack,
          status: error.status,
          origin: error.origin
        }
      });

      this.setHeaders(response, error, error.origin);

      response.status(error.status).send(toHTML(error.message));

      return;
    }

    if (typeof error === "string") {
      response.status(404).send(toHTML(error));

      return;
    }

    request.log.error({
      error: {
        status: 500,
        message: error.message,
        stack: error.stack,
        origin: error.origin
      }
    });

    this.setHeaders(response, error, error.origin);

    response.status(error.status || 500).send("Internal Error");

    return;
  }

  setHeaders(response: Express.Response, ...args: IResponseError[]) {
    let hErrors: any = [];

    args
      .filter(o => !!o)
      .forEach(({headers, errors}: IResponseError) => {
        if (headers) {
          response.set(headers);
        }

        if (errors) {
          hErrors = hErrors.concat(errors);
        }
      });

    if (hErrors.length) {
      response.set(this.headerName, JSON.stringify(hErrors));
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

With it's possible to change the default implementation like this:

import {Err, GlobalErrorHandlerMiddleware, OverrideProvider, Req, Res} from "@tsed/common";

@OverrideProvider(GlobalErrorHandlerMiddleware)
export class MyGEHMiddleware extends GlobalErrorHandlerMiddleware {

  use(@Err() error: any,
      @Req() request: Req,
      @Res() response: Res): any {

    // DO SOMETHING

    return super.use(error, request, response);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

TIP

By default, the server import automatically your middlewares matching with this rules ${rootDir}/middlewares/**/*.ts (See componentScan configuration).

.
├── src
│   ├── controllers
│   ├── services
│   ├── middlewares
│   └── Server.ts
└── package.json
1
2
3
4
5
6
7

If not, just import your middleware in your server or edit the componentScan configuration.

import {ServerLoader, ServerSettings} from "@tsed/common";
import "./src/other/directory/MyGEHMiddleware";

@ServerSettings({
    ...
})
export class Server extends ServerLoader {
  
 
}
1
2
3
4
5
6
7
8
9
10