9-error
You can easily customize all error responses generated by Dream, whether from
your application, or at lower levels in the HTTP stack. This is done by passing
the ~error_handler parameter to
Dream.run. The easiest way to get
an error_handler is to call
Dream.error_template:
let my_error_template debug_info suggested_response =
let status = Dream.status suggested_response in
let code = Dream.status_to_int status
and reason = Dream.status_to_string status in
suggested_response
|> Dream.with_body begin
<html>
<body>
<h1><%i code %> <%s reason %></h1>
% begin match debug_info with
% | None -> ()
% | Some debug_info ->
<pre><%s debug_info %></pre>
% end;
</body>
</html>
end
|> Lwt.return
let () =
Dream.run ~error_handler:(Dream.error_template my_error_template)
@@ Dream.logger
@@ Dream.not_found
$ dune exec --root . ./error.exe
We kept the template simple for the sake of the example, but this is where you'd put in neat graphics to make a beautiful error page!
This app doesn't show debug information by default. However, try adding
~debug:true to Dream.run,
rebuilding the app, and accessing it again.
Dream will call the error template for every single error response it generates:
4xxand5xxerror responses returned by your application.- Exceptions raised by your application.
- Whenever the lower-level HTTP servers want to send a response; for instance,
a
400 Bad Requestdue to malformed headers.
The suggested_response argument contains a skeleton response. It is either the
response returned by your application in case (1), an empty 500 Internal Server Error if your application raised an exception (2), or a 500 Internal Server Error or 400 Bad Request suggested by the HTTP servers in response to
lower-level failures (3).
The easiest thing to do is to decorate suggested_response with a fancy
response body, and maybe add some headers. However, you can do anything here,
including build up and return a completely new response.
debug_info is None by default. If you passed ~debug:true to
Dream.run, it is Some of a
string that contains the debug info that we saw in the previous example,
8-debug.
If you don't customize the error handler, Dream defaults to sending only empty responses, so that your application can be fully localization-friendly — even at the lowest levels. Dream carefully avoids hardcoding any strings, even to the point of intercepting strings generated by its HTTP dependencies.
Next steps:
a-logshows how to write messages to Dream's log.b-sessionfinally returns to Web development proper, with session management for associating state with clients.