Error Pages / Status Codes
During web requests, Pode has some default status codes that can be returned throughout a request's lifecycle:
200
on success400
when the query string or payload are invalid403
when access to the server is unauthorised404
if the route can't be found429
if the rate limit is reached500
for a complete failure
Status codes that are 400+ will be rendered as an error page, unless the -NoErrorPage
switch is passed to the Set-PodeResponseStatus
function. Pode itself has inbuilt error pages (HTML, JSON, and XML), but you can override these pages using custom error pages (described below).
If the error page being generated is dynamic, then the following $data
is supplied and can be used the same as in views:
- The HTTP status code
- A description for the status
- The URL that threw the error
- The content-type of the error page being generated
They're also supplied details of any exception passed to the Set-PodeResponseStatus
function, which can be rendered if enabled via the server.psd1
configuration file.
Status Codes
The Set-PodeResponseStatus
function allows you to set your own status code on the response, as well as a custom description. If the status code was triggered by an exception being thrown, then you can also supply this so it can be rendered on any error pages.
The following example will set the status code of the response to be 418
:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/teapot' -ScriptBlock {
Set-PodeResponseStatus -Code 418
}
}
Where as this example will set the status code to 500
with a custom description, and the exception that caused the error:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeRoute -Method Get -Path '/eek' -ScriptBlock {
try {
# logic
}
catch {
Set-PodeResponseStatus -Code 500 -Description 'oh no! something went wrong!' -Exception $_
}
}
}
Error Pages
When a response is returned with a status code of 400+, then Pode will attempt to render these as styled error pages. By default, Pode has inbuilt error pages that will be used (these show the status code, description, the URL, and if enabled the exception message/stacktrace).
The inbuilt error pages are of types HTML, JSON, and XML. By default Pode will always attempt to use the HTML error pages however, if you set, say strict content typing, then Pode will also attempt to use the JSON/XML error pages if the request's content type header is set appropriately.
Custom
In Pode you can use custom error pages, so you can stylise your own rather than using the inbuilt ones that come with Pode.
To use your own custom error pages you have to place them within an /errors
directory, at the root of your server (similar to /views
and /public
).
These pages should be called the name of a status code, the content type of the page, and an optional view engine extension:
<code>.<type>[.<engine>] # ie: 400.html, or 404.json.pode
Or, you can use a default error page which will be used for any status codes that doesn't have a specific page define:
default.<type>[.<engine>] # ie: default.html, or default.json.pode
An example file structure for /errors
is as follows:
/errors
default.html
404.html
404.json
500.html.pode
By default Pode will always generate error pages as HTML, unless you enable strict content typing or routes patterns (detailed later).
Important
To use error pages with a view engine (such as .pode
), you need to use the Set-PodeViewEngine
function in your server.
Dynamic Data
If you're using a dynamic view engine to render the error pages, then like views
, there will be a $data
variable that you can use within the error page file. The $data
variable will have the following structure:
@{
Url = [string]
Status = @{
Code = [int]
Description = [string]
}
Exception = @{
Message = [string]
StackTrace = [string]
Line = [string]
Category = [string]
}
ContentType = [string]
}
Note
If you've disabled the showing of exceptions, then the Exception
property will be $null
.
Exceptions
Above you'll see that the exception supplied to status
will also be supplied to any dynamic error pages. By default this is disabled, but you can enable the viewing of exceptions on the error page by using the server.psd1
configuration file:
@{
Web = @{
ErrorPages = @{
ShowExceptions = $true
}
}
}
Once set to true
, any available exception details for status codes will be available to error pages - a useful setting to have in a server.dev.psd1
file.
Important
This setting is not recommended for production environments due to the security risk associated with exposing internal exception details.
Content Types
Using the server.psd1
configuration file, you can define which file content types to attempt when generating error pages for routes. You can either:
- Define a default content type that will apply to every route, or
- Enable strict content typing to use a route/request's content type, or
- Define patterns to match multiple route paths to set content types on mass
Default
To define a default content type for everything, you can use the following configuration. With this, any error thrown in any route will attempt to render an HTML error page:
@{
Web = @{
ErrorPages = @{
Default = "text/html"
}
}
}
Route Patterns
You can define patterns to match multiple route paths, and any route that matches, when an error page is being generated, will attempt to generate an error page for the content type set.
For example, the following configuration in your server.psd1
file would bind all /api
routes to application/json
error pages, and then all /status
routes to text/xml
error pages:
@{
Web = @{
ErrorPages = @{
Routes = @{
"/api/*" = "application/json"
"/status/*" = "text/xml"
}
}
}
}
Strict Typing
You can enable strict content typing in the server.psd1
file. When enabled, Pode will attempt to generate an error page that matches the route/request's content type.
For example: if the request's Content-Type
header is set to application/json
(or you're using route content types), and you have strict content typing enabled, then Pode will attempt to use a JSON error page.
To enable strict content typing, you can use the following:
@{
Web = @{
ErrorPages = @{
StrictContentTyping = $true
}
}
}
Type Precedence
The content type that will used, when attempting to generate an error page, will be determined by the following order:
- A content type is supplied directly to the
status
function (via-ContentType
). - An error page content type is supplied directly to the
route
function (via-ErrorType
). - The route matches a pattern defined in the configuration file.
- Strict content typing is enabled in the configuration file.
- A default error page content type is defined in the configuration file.
- use the default of HTML.
File Precedence
The error page file that will used will be determined by the following order. This order will be done for each step that matches in the above type precedence:
<code>.<type>
- ie:404.json
<code>.<type>.<engine>
- ie:404.json.pode
<code>.<engine>
- ie:404.pode
default.<type>
- ie:default.json
default.<type>.<engine>
- ie:default.json.pode
default.<engine>
- ie:default.pode
- Inbuilt pages
Example Page
The following is a simple default.html.pode
dynamic error page example, which will render the status code and description - and if available, the exception message and stacktrace:
<html>
<head>
<title>$($data.status.code) Error</title>
</head>
<body>
<h1>$($data.status.code) Error</h1>
<p>Description: $($data.status.description)</p>
$(if ($data.exception) {
"<pre>
$($data.exception.message)
$($data.exception.stacktrace)
</pre>"
})
</body>
</html>