前言
第一部分: 半协程调度器
- 统一生成器接口
- 生成器迭代
- 生成器返回值
- 生成器委托
- 改写 return
- 抽象异步模型
- 引入异常处理
- 异常: 嵌套任务透传
- 异常: 传递流程
- 异常: 重新进行 CPS 变换
- 异常: 重新加入 Async
- Syscall 与 Context
- 调度器: 里程碑
- spawn
- callcc
- race 与 timeout
- all 与 parallel
- channel 与协程间通信
- 无缓存 channel
- 缓存 channel
- channel 演示
- FutureTask 与 fork
第二部分: Koa
- 穿越地心之旅
- 洋葱圈模型
- rightReduce与中间件compose
- Koa::Application
- Koa::Context
- Koa::Request
- Koa::Response
- Koa - HelloWorld
- Middleware Interface
- Middleware: 全局异常处理
- Middleware: Router
- Middleware: 请求超时
- 一个综合示例
附录
参考
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Middleware: 全局异常处理
Middleware: 全局异常处理
我们在岩浆的实例其实已经注意到了,compose 的连接方式,让我们有能力精确控制异常。
Koa中间件最终行为强依赖注册顺序,比如我们这里要引入的异常处理,必须在业务逻辑中间件前注册,才能捕获后续中间件中未捕获异常,回想一下我们的调度器实现的异常传递流程。
<?php
class ExceptionHandler implements Middleware
{
public function __invoke(Context $ctx, $next)
{
try {
yield $next;
} catch (\Exception $ex) {
$status = 500;
$code = $ex->getCode() ?: 0;
$msg = "Internal Error";
// HttpException的异常通常是通过Context的throw方法抛出
// 状态码与Msg直接提取可用
if ($ex instanceof HttpException) {
$status = $ex->status;
if ($ex->expose) {
$msg = $ex->getMessage();
}
}
// 这里可这对其他异常区分处理
// else if ($ex instanceof otherException) { }
$err = [ "code" => $code, "msg" => $msg ];
if ($ctx->accept("json")) {
$ctx->status = 200;
$ctx->body = $err;
} else {
$ctx->status = $status;
if ($status === 404) {
$ctx->body = (yield Template::render(__DIR__ . "/404.html"));
} else if ($status === 500) {
$ctx->body = (yield Template::render(__DIR__ . "/500.html", $err));
} else {
$ctx->body = (yield Template::render(__DIR__ . "/error.html", $err));
}
}
}
}
}
$app->υse(new ExceptionHandler());
可以将FastRoute与Exception中间件结合,很容可以定制一个按路由匹配注册的异常处理器,留待读者自行实现。
顺序问题再比如session中间件,需要优先于业务处理中间件,
而像处理404状态码的中间件,则需要在upstream流程中(逆序)的收尾阶段,我们仅仅只关心next后逻辑:
<?php
function notfound(Context $ctx, $next)
{
yield $next;
if ($ctx->status !== 404 || $ctx->body) {
return;
}
$ctx->status = 404;
if ($ctx->accept("json")) {
$ctx->body = [
"message" => "Not Found",
];
return;
}
$ctx->body = "<h1>404 Not Found</h1>";
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论