Revel的500页面必须使用app/views/errors/500.html模板且仅在prod模式生效,需确保run.mode=prod、PanicFilter在Filter链中正确配置、模板包含标准布局结构(如{{template "header.html" .}}),否则将显示空白页或调试信息。

Revel 的 500 页面必须用 app/views/errors/500.html,且仅在 prod 模式生效
Revel 不会渲染你随便放的 500.tpl 或 errors/500.html(带子目录),它只认硬编码路径 app/views/errors/500.html。这个文件必须存在,且 run.mode = prod 已启用——dev 模式下无论你怎么配,Revel 都强制返回带堆栈的调试页,这是框架行为,无法绕过。
常见错误现象:访问一个会 panic 的路由(比如故意在 controller 里写 panic("test")),却看到纯白页或 JSON 错误,说明要么文件路径不对,要么还在 dev 模式。
-
app/views/errors/500.html必须手动创建,Revel 不自动建errors目录 - 文件名必须严格为
500.html,大小写、后缀、空格都不能错 - conf/app.conf 中
run.mode = prod必须位于 [prod] 区块,且不能被 [dev] 区块覆盖 - 启动时终端要出现
Running in 'prod' mode字样,否则配置没生效
模板里要用 Revel 标准布局结构,否则 CSS 和导航全丢
直接写个裸 HTML: 是无效的——Revel 的 Server Error
500.html 不是独立页面,而是嵌入主布局的片段。它必须调用 {{template "header.html" .}} 和 {{template "footer.html" .}},否则页面会失去样式、脚本和导航栏,变成孤立的错乱文本。
最小可用模板结构:
{{set . "title" "Internal Server Error"}}
{{template "header.html" .}}
<div class="error-container">
<h1>Oops! Something went wrong.</h1>
<p>Our team has been notified.</p>
</div>
{{template "footer.html" .}}
-
{{set . "title" ...}}是必须的,否则header.html可能渲染空 title - 不要试图在
500.html里写,Revel 会把它塞进已有 layout 里 - 模板中可安全使用
{{.errors}}和{{.flash}},但 panic 场景下它们通常为空
500 页面不显示?先确认 PanicFilter 是否在 Filter 链里
Revel 默认靠 PanicFilter 捕获 panic 并触发 500.html 渲染。如果自定义了 app/init.go 中的 Filters 列表,却删掉了或挪动了 PanicFilter,500 页面就完全不会走模板流程,而是直接返回空白响应或原始 panic 信息。
检查 app/init.go 中的 filter 定义,确保包含这一行:
revel.PanicFilter
-
PanicFilter必须在RouterFilter之后、ActionInvoker之前,顺序错会导致 panic 未被捕获 - 如果用了自定义 recover 逻辑(比如手写了 defer+recover),会和
PanicFilter冲突,导致 500 页面失效 - 日志里出现
Recovered from panic但没渲染页面,大概率是 filter 顺序或缺失问题
线上环境别忘了关掉 debug 输出,否则 500 页面可能被覆盖
Revel 在 run.mode = prod 下默认禁用 debug 输出,但如果 conf/app.conf 里显式写了 results.debug = true(尤其从 dev 环境复制配置时容易漏删),它会强制把 panic 堆栈打到响应体里,直接覆盖 500.html 的渲染结果。
务必检查 conf/app.conf 中没有以下配置项:
results.debug = true-
results.pretty = true(虽不直接干扰 500,但在 prod 下应禁用) - 任何以
results.开头、值为true的调试相关配置
最稳妥的做法:上线前用 grep -r "results\." conf/ 扫一遍,删掉所有非必需的 results.* 行。











