在使用HttpException手动抛出异常时,希望跳转到自定义的错误页面,官方的文章中是这样描述的。

可以使用\think\exception\HttpException类来抛出异常

// 抛出 HTTP 异常
throw new \think\exception\HttpException(404, '异常消息', null, [参数]);

一旦抛出了HttpException异常,可以支持定义单独的异常页面的模板地址,只需要在应用配置文件中增加:

'http_exception_template'    =>  [
// 定义404错误的重定向页面地址
404 => APP_PATH.'404.html',
// 还可以定义其它的HTTP status
401 => APP_PATH.'401.html',
]

然而如果你这些都做完了,关闭调试模式,你会发现还是跳转到官方自定义的页面上去了,并且你发现http状态码是500,这是代码有问题啊,我抛出的是404啊。

然后打开log日志,你会发现果然报错了。

[ error ] [1]Uncaught think\exception\TemplateNotFoundException: template not exists:view/layout.html in /Applications/MAMP/htdocs/best.shiqidu.com/thinkphp/library/think/Template.php:1082
Stack trace:

这。。。
可怎么办。。。

只能看源码找问题了。

你会发现这个方法被调用了两次。

/**
* 解析模板文件名
* @access private
* @param string $template 文件名
* @return string|false
*/
private function parseTemplateFile($template)
{...}

第一次时$template模板文件时能找到的。但是第二次也是一个相对路径view/layout,所以报错了,继续顺藤摸瓜,发现这个函数。

/**
* 编译模板文件内容
* @access private
* @param string $content 模板内容
* @param string $cacheFile 缓存文件名
* @return void
*/
private function compiler(&$content, $cacheFile)
{
// 判断是否启用布局
if ($this->config['layout_on']) {
if (false !== strpos($content, '{__NOLAYOUT__}')) {
// 可以单独定义不使用布局
$content = str_replace('{__NOLAYOUT__}', '', $content);
} else {
// 读取布局模板
$layoutFile = $this->parseTemplateFile($this->config['layout_name']);
if ($layoutFile) {
// 替换布局的主体内容
$content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));
}
}
} else {
$content = str_replace('{__NOLAYOUT__}', '', $content);
}
...

关键就是这里了,如果你没有{__NOLAYOUT__}这个表示的话,它在渲染自定义404页面时会去加载布局文件(如果你在配置文件里开启了布局,如果没开启layout=true,也不会报这个错)。
而这个布局文件的路径是一个相对路径,这时如果你抛出异常的地方不是在applicationcontroller里,就找不到布局文件了。所以就报错了。

怎么解决呢?其实也很简单。给自定义的404页面加上{__NOLAYOUT__}就行了。

这一点官方文档没有说明,还在坑里的同学可以参考改下。

最新文章

  1. [No00006C]文件名复制,归档小助手【自己写的小工具,希望能帮助大家】
  2. javascript学习目录
  3. 【HDU 1150】Machine Schedule(二分图匹配)
  4. Xml命名空间浅析
  5. Solr搜索基础
  6. IdentityServer4 实现 OAuth 2.0(密码模式 - HTTP Post 方式)
  7. Python入门之PyCharm的快捷键与常用设置和扩展(Win系统)
  8. PhantomJS命令行选项
  9. 神经网络MPLClassifier分类
  10. SVG初尝试之path
  11. 【HDFS API编程】删除文件
  12. OJ:奇怪的类复制
  13. css把容器级别(div...)标签固定在一个位置(在页面最右边)
  14. 通过安装memadmin对memcache进行可视化管理
  15. [ACM-ICPC 2018 徐州赛区网络预赛][D. Easy Math]
  16. (拼接SQL语句)mysql中date类型,datetime类型
  17. 常见的HTTP报头(头参数)
  18. MongoDB的增删查改基本操作
  19. Journal entry of the thirteenth chapter to chapter seventeenth(第十三章和十七章阅读与疑问)
  20. java保存json格式数据,保存字符串和读取字符串

热门文章

  1. Arduino初学
  2. 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)
  3. Docker 跨主机网络方案分析
  4. PHP多进程消费队列
  5. python_code list_2
  6. MYSQL数据库设计规范与原则
  7. @SpringBootApplication注解理解
  8. Java历程-初学篇 Day01初识java
  9. 玩转Web之SSH--Heibernate (一)---第一个demo
  10. pdb 调试