Error handling
Yggdrasil Server has a built-in error handling mechanism to generate status
pages when something goes wrong. To use it, throw a YggdrasilServerStatus
object anywhere in your request handler:
if (route === undefined) throw new YggdrasilServerStatus(ygg, 404, "INVALID_ROUTE", "The page you're trying to load doesn't exist.");
For your convenience, Yggdrasil Server also provides a ygg.status function that
creates a YggdrasilServerStatus with the context pre-set, and an assert function
that throws a YggdrasilServerStatus for you upon failure:
if (route === undefined) throw ygg.status(404, "INVALID_ROUTE", "The page you're trying to load doesn't exist.");
// or
ygg.assert(route !== undefined, 404, "INVALID_ROUTE", "The page you're trying to load doesn't exist.");
YggdrasilStatus and server context
Yggdrasil Server also provides a YggdrasilStatus object that is functionally
the same as YggdrasilServerStatus. However, YggdrasilServerStatus keeps
a reference to the ygg context at the time of the error, while YggdrasilStatus
does not have an associated ygg context. YggdrasilStatus is therefore
primarily designed for handling YggdrasilServerStatus exceptions outside
of Yggdrasil Server, like exceptions from a client-side Yggdrasil Server Conduit
client.
The ygg context included with YggdrasilServerStatus is useful for getting
helpful values for debugging out from the context when the error is caught.
For example, if an YggdrasilServerStatus is thrown in a Yggdrasil Server Conduit
handler, the ygg context in the thrown YggdrasilServerStatus will have
extended Yggdrasil Server Conduit attributes. It also enables the optional
generateStatusMessage function to programmatically generate status messages
for YggdrasilServerStatus thrown by your server. So, you should never throw a
YggdrasilStatus object from within Yggdrasil server.
Catching errors
You should always check if a caught Error is an instance of YggdrasilStatus when
catching Yggdrasil Server errors. You should only check for YggdrasilServerStatus
to get the associated ygg context, keeping in mind that it is only available on
a best-effort basis.
YggdrasilStatus attributes
The YggdrasilStatus object contains the following attributes:
status: The HTTP status code to return. The name of the status code should match the nature of the exception.statusCode: A custom status code (something like "AUTH_REQUIRED"). This should be a brief exception ID that should allow you to identify where the exception was thrown from in your code, and also allow users to identify the error through bug reports, web searches, etc.statusMessage: A custom status message to show to the user to help them understand the nature of the error, how they might resolve it, additional details, etc.statusArgs: Any custom properties you may want to associate with the thrown status. The type of this attribute is set by your YggdrasilServer app types for construction, but when you catch aYggdrasilStatusobject, thestatusArgsmay be different if it was thrown internally by Yggdrasil Server or by some other part of code.ygg: Theyggcontext active when the exception was thrown. (Only onYggdrasilServerStatusobjects)
Built-in errors
Yggdrasil Server itself may throw a YggdrasilStatus if your configuration causes an
unworkable state. When Yggdrasil Server itself throws an error, it will use an status
code prefixed with YGG_. Please don't prefix any of your own status codes with YGG_.
Just because one of these errors is thrown doesn't mean your app is badly configured, however.
For example, if your server's base URL is in a subdirectory, and it's deployed behind a
reverse proxy that routes other directories elsewhere, you may receive a
YGG_BASE_URL_MISMATCH when you try to load the root path directly (without going through
the proxy), but this would be expected since your reverse proxy would otherwise
route that path somewhere else on the user-facing URL.
List of built-in errors
| HTTP status code | Yggdrasil status code | Description |
|---|---|---|
| 404 | YGG_BASE_URL_MISMATCH | Thrown when your base URL indicates that your server is deployed in a sub-directory (e.g. /app), but the requested URL does not use that prefix. |
| 404 | YGG_ROUTE_NOT_FOUND | Thrown when YggdrasilRouter can't find a route that matches the request's path. |
| 405 | YGG_ROUTE_METHOD_MISMATCH | Thrown when YggdrasilRouter finds route(s) that matches the request's path, but none of them match the request's method. |
| 404 | YGG_API_NOT_FOUND | Thrown when YggdrasilConduitServer can't find a Conduit API implementation that matches the request. |
| 400 | YGG_BAD_API_REQUEST | Thrown when YggdrasilConduitServer detects an invalid Conduit API request. |
| 500 | YGG_BAD_API_RESPONSE | Thrown when the Yggdrasil Conduit client cannot parse the response received from a Yggdrasil Conduit server. |
| 500 | YGG_BADLY_CONFIGURED | Thrown when Yggdrasil Server is unable to proceed due to a misconfiguration, such as missing a required option, contradictory settings, etc. The error message describes the nature of the misconfiguration. |
Status pages
When a YggdrasilStatus object is thrown and uncaught by your handler, Yggdrasil Server will
return a Response with the corresponding HTTP status code and a generated status page:
| Request Accept | Response type | Description |
|---|---|---|
application/json | application/json | Returns a JSON object with the following keys: success: false, status: the HTTP status code, error: the YggdrasilStatus status code, message: the status message. |
text/html | text/html | Calls ygg.options.generateHtmlStatusPage() if this is something you've implemented. |
| Anything else | text/plain | Returns a presentable plaintext status page detailing the error. |
Uncaught errors
The bulk of this document details how Yggdrasil Server handles uncaught YggdrasilStatus
objects to generate a status page. Please keep in mind that this behavior only applies
to YggdrasilStatus objects. Any other errors that happen in your code will remain
uncaught, and it's up to you to determine how those should be handled.