handle_errors
设置错误处理程序。
当常规 HTTP 请求处理程序返回错误时,正常处理会停止并调用错误处理程序。错误处理程序形成一条路由,和普通路由完全相同,能够执行普通路由所能做的任何操作。这使得在处理 HTTP 请求错误时能够获得强大的控制力和灵活性。例如,你可以提供静态错误页面、模板化错误页面,或将请求反向代理到另一个后端来处理错误。
该指令可以针对不同的状态码重复使用,以便对不同错误做不同处理。如果未指定状态码,则会匹配任何错误,当其他错误处理程序都不匹配时作为回退。
请求的上下文会被传递到错误路由中,因此在请求上下文中设置的任何值,例如 站点根目录 或 vars,也会在错误处理程序中保留。此外,在处理错误时还可使用 新占位符。
注意某些指令,例如可能会写入一个被归类为错误的 HTTP 状态码响应的 reverse_proxy,不会触发错误路由。
你可以使用 error 指令根据自己的路由决策显式触发错误。
语法
handle_errors [<status_codes...>] {
<directives...>
}
-
<status_codes...> 是要与正在处理的错误匹配的一个或多个 HTTP 状态码。状态码可以是三位数,也可以使用特殊形式
4xx或5xx,分别匹配 400-499 或 500-599 范围内的所有状态码。如果未指定状态码,则会匹配任何错误,当其他错误处理程序都不匹配时作为回退。 -
<directives...> 是一行一个的 HTTP 处理器 directives 和 matchers 的列表。
占位符
在处理错误时可用以下占位符。它们是 Caddyfile 简写,对应于可以在 HTTP 服务器的错误路由的 JSON 文档 中找到的完整占位符。
| Placeholder | 说明 |
|---|---|
{err.status_code} |
建议的 HTTP 状态码 |
{err.status_text} |
与建议状态码关联的状态文本 |
{err.message} |
错误信息 |
{err.trace} |
错误来源 |
{err.id} |
该错误发生的标识符 |
示例
基于状态码的自定义错误页面(例如为 404 错误提供名为 404.html 的页面)。注意在 handle_errors 中运行时,file_server 会保留错误的 HTTP 状态码(假设你事先在站点中设置了 站点根目录):
handle_errors {
rewrite * /{err.status_code}.html
file_server
}
使用 templates 写入自定义错误信息的单一错误页面:
handle_errors {
rewrite * /error.html
templates
file_server
}
如果你只想为某些错误码提供自定义错误页面,可以事先使用 file 匹配器检查自定义错误文件是否存在:
handle_errors {
@custom_err file /err-{err.status_code}.html /err.html
handle @custom_err {
rewrite * {file_match.relative}
file_server
}
respond "{err.status_code} {err.status_text}"
}
将请求反向代理到一个更专业、擅长处理 HTTP 错误的服务器以提升你的体验 😸:
handle_errors {
rewrite * /{err.status_code}
reverse_proxy https://http.cat {
header_up Host {upstream_hostport}
replace_status {err.status_code}
}
}
简单使用 respond 返回错误代码和名称:
handle_errors {
respond "{err.status_code} {err.status_text}"
}
为特定错误码做不同处理:
handle_errors 404 410 {
respond "It's a 404 or 410 error!"
}
handle_errors 5xx {
respond "It's a 5xx error."
}
handle_errors {
respond "It's another error"
}
上述行为与下面的配置相同,后者使用 expression 匹配器针对状态码进行匹配,并使用 handle 实现互斥:
handle_errors {
@404-410 `{err.status_code} in [404, 410]`
handle @404-410 {
respond "It's a 404 or 410 error!"
}
@5xx `{err.status_code} >= 500 && {err.status_code} < 600`
handle @5xx {
respond "It's a 5xx error."
}
handle {
respond "It's another error"
}
}