Error Handling

Tips for handling errors nicely for the user.

# Report Exception

Sometimes an Exception (exn) will happen during the lifecycle of an http request/response. You may want to respond with specific http codes, in which case you should use the typical response functions. There is also a convenience function to report exceptions Res.reportException. Which will bypass the current request handler and instead apply the errorHandler supplied when the naboris http server was created.

1exception BadThing(string);
2
3let startServer = () => {
4  let port = 9000;
5  let serverConfig = Naboris.ServerConfig.create()
6    |> Naboris.ServerConfig.setRequestHandler((route, req, res) =>
7        switch (Naboris.Route.meth(route), Naboris.Route.path(route)) {
8          | (GET, ["error"]) =>
9            Naboris.Res.reportException(BadThing("something bad"), req, res)
10          | _ =>
11            Naboris.Res.status(404, res)
12              |> Naboris.Res.text(req, "Not Found.");
13        })
14    |> Naboris.Server.setErrorHandler((error, _route) => {
15      let headers = [];
16      let body = switch (error) {
17        | BadThing(text) => text
18        | _ => "Unknown Error"
19      };
20      // expects a promise of a tuple containing headers and the body string
21      Lwt.return((headers, body));
22    });
23
24  Naboris.listenAndWaitForever(port, serverConfig);
25}
26
27Lwt_main.run(startServer());
1exception BadThing of string
2
3let start_server ()=
4  let port = 9000 in
5  let server_config = Naboris.ServerConfig.create()
6    |> Naboris.ServerConfig.setRequestHandler(fun route req res ->
7      match (Route.meth route, Route.path route) with
8        | (GET, ["error"]) ->
9          Naboris.Res.reportException (BadThing "") req res
10        | _ ->
11          Naboris.Res.status 404 res
12            |> Naboris.Res.text req "Not Found.")
13    |> Naboris.ServerConfig.setErrorHandler(fun error route ->
14      let headers = [] in
15      let body = match (error) with
16        | BadThing text -> text
17        | _ -> "Unknown Error" in
18      (* expects a promise of a tuple containing headers and the body string *)
19      Lwt.return((headers, body))) in
20
21  Naboris.listenAndWaitForever port server_config
22
23let _ = Lwt_main.run(main ())

# Error Handler

The above helper function Res.reportException will respond to the current http request using the configured errorHandler. This handler is provided by your ServerConfig.t and is optional. By default it will respond with a plain/text type and a body containing the output of Printexc.to_string on the exn supplied.

Note: This helper always responds with a 500 code.

Use ServerConfig.setErrorHandler and provide an ErrorHandler.t.

1// ServerConfig module
2let setErrorHandler: (ErrorHandler.t, t('sessionData)) => t('sessionData);
1(* ServerConfig module *)
2val setErrorHandler : ErrorHandler.t -> 'sessionData t -> 'sessionData t

ErrorHandler.t is a function which takes as arguments the exn passed in to Res.reportException and the Route.t of the current request. It then expects a return value of an Lwt promise of a tuple of (headers * body). headers being a (string * string) list and body being a string.

1// ErrorHandler module
2type t = (exn, Route.t) => Lwt.t((list((string, string)), string));
1(* ErrorHandler module *)
2type t = exn -> Route.t -> ((string * string) list * string) Lwt.t
Support us on GitHub

Star, follow, fork

Star Fork

Found a typo? a bug? or something that just doesn't make any sense? Help improve these docs by opening a github issue.

naboris source code is licensed MIT.
It can be used, copied, and modified free of charge. However, the software is provided "as is" without any warranties. Click the link above for more information.