Redirection and Error¶
Redirection, client and server errors are handled via a simple exception mechanism.
In a HandlerCallback
, you may throw any of Informational
, Success
,
Redirection
, ClientError
and ServerError
predefined error domains
rather than setting the status and returning from the function.
It is possible to register a handler on the Router to handle a specific status code.
app.use ((req, res, next) => {
try {
return next ();
} catch (Redirection.PERMANENT red) {
// handle a redirection...
}
}));
Default handling¶
Changed in version 0.3: Default handling is not assured by the Basic middleware.
The Router can be configured to handle raised status by setting the response status code and headers appropriately.
app.use (basic ());
app.get ("/", () => {
throw new ClientError.NOT_FOUND ("The request URI '/' was not found.");
});
To handle status more elegantly, see the Status middleware.
app.use (status (Status.NOT_FOUND, (req, res, next, ctx, err) => {
// handle 'err' properly...
}));
The error message may be used to fill a specific Response headers or the response body. The following table describe how the router deal with these cases.
Status | Header | Description |
---|---|---|
Informational.SWITCHING_PROTOCOLS | Upgrade | Identifier of the protocol to use |
Success.CREATED | Location | URL to the newly created resource |
Success.PARTIAL_CONTENT | Range | Range of the delivered resource in bytes |
Redirection.MOVED_PERMANENTLY | Location | URL to perform the redirection |
Redirection.FOUND | Location | URL of the found resource |
Redirection.SEE_OTHER | Location | URL of the alternative resource |
Redirection.USE_PROXY | Location | URL of the proxy |
Redirection.TEMPORARY_REDIRECT | Location | URL to perform the redirection |
ClientError.UNAUTHORIZED | WWW-Authenticate | Challenge for authentication |
ClientError.METHOD_NOT_ALLOWED | Allow | Comma-separated list of allowed methods |
ClientError.UPGRADE_REQUIRED | Upgrade | Identifier of the protocol to use |
The following errors does not produce any payload:
Information.SWITCHING_PROTOCOLS
Success.NO_CONTENT
Success.RESET_CONTENT
Success.NOT_MODIFIED
For all other domains, the message will be used as a text/plain
payload
encoded with UTF-8
.
The approach taken by Valum is to support at least all status defined by libsoup-2.4 and those defined in RFC documents. If anything is missing, you can add it and submit us a pull request.
Informational (1xx)¶
Informational status are used to provide a in-between response for the requested resource. The Response body must remain empty.
Informational status are enumerated in Informational
error domain.
Success (2xx)¶
Success status tells the client that the request went well and provide
additional information about the resource. An example would be to throw
a Success.CREATED
error to provide the location of the newly created
resource.
Successes are enumerated in Success
error domain.
app.get ("/document/<int:id>", (req, res) => {
// serve the document by its identifier...
});
app.put ("/document", (req, res) => {
// create the document described by the request
throw new Success.CREATED ("/document/%u".printf (id));
});
Redirection (3xx)¶
To perform a redirection, you have to throw a Redirection
error and use the
message as a redirect URL. The Router will automatically set the
Location
header accordingly.
Redirections are enumerated in Redirection
error domain.
app.get ("/user/<id>/save", (req, res) => {
var user = User (req.params["id"]);
if (user.save ())
throw new Redirection.MOVED_TEMPORAIRLY ("/user/%u".printf (user.id));
});
Client (4xx) and server (5xx) error¶
Like for redirections, client and server errors are thrown. Errors are
predefined in ClientError
and ServerError
error domains.
app.get ("/not-found", (req, res) => {
throw new ClientError.NOT_FOUND ("The requested URI was not found.");
});
Errors in next¶
The next
continuation is designed to throw these specific errors so that
the Router can handle them properly.
app.use ((req, res, next) => {
try {
return next ();
} catch (ClientError.NOT_FOUND err) {
// handle a 404...
}
});
app.get ("/", (req, res, next) => {
return next (); // will throw a 404
});
app.get ("/", (req, res) => {
throw new ClientError.NOT_FOUND ("");
});