You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Raku Cro应用中实现全局异常处理

Cro应用全局异常处理解决方案

你遇到的问题是Cro路由异常处理的作用域限制导致的,并非线程相关问题,Cro原生支持全局异常捕获,不需要为每个路由单独编写CATCH块,两种常用实现方案如下:

方案1:服务级全局异常处理器(最推荐)

在初始化Cro::HTTP::Server时传入exception-handler回调参数,该回调会自动捕获所有路由处理过程中未被内部CATCH块消费的异常,无需修改现有业务路由代码。
示例代码:

use Cro::HTTP::Server;
use Cro::HTTP::Router;

# 你的现有业务路由集合
my $business-routes = route {
    # 原有数十条路由无需调整
    get -> 'demo' {
        die "测试抛出异常";
    }
};

# 启动服务时配置全局异常兜底
my $server = Cro::HTTP::Server.new(
    port => 8080,
    application => $business-routes,
    exception-handler => sub ($exception, $response) {
        # 统一处理异常逻辑:日志记录、自定义响应等
        note "系统异常:$exception";
        $response.status = 500;
        $response.set-body: "服务内部错误:{$exception.message}";
    }
);

$server.start;
sleep;

方案2:顶层路由块CATCH统一处理

如果希望异常处理逻辑和路由定义放在一起,可以将所有子路由通过include挂载到同一个顶层路由块,在顶层路由的最开头定义全局CATCH块。
示例代码:

# 子路由模块示例(可以拆分到不同文件)
my $user-routes = route {
    get -> 'user', Int $id { ... }
}
my $order-routes = route {
    post -> 'order' { ... }
}

# 顶层入口路由
my $app = route {
    # 全局CATCH必须放在所有路由定义最前面
    CATCH {
        default {
            note "捕获路由异常:$_";
            content 'application/json',
                '{"code":500,"msg":"服务器处理失败"}',
                status => 500;
        }
    }
    # 挂载所有业务子路由
    include 'api/v1' => $user-routes;
    include 'api/v1' => $order-routes;
    # 其他顶层路由
    get -> 'health' { content 'text/plain', 'ok' }
}

常见问题说明

  1. 之前你配置的顶层CATCH不生效,通常是因为没有用include挂载子路由,而是将多个路由块独立传入服务,导致CATCH作用域没有覆盖到子路由执行上下文。
  2. 如果某个路由内部已经定义了CATCH块且没有重新抛出异常,全局处理器不会重复处理该异常,符合常规异常处理的冒泡逻辑。
  3. 服务级的exception-handler优先级最低,适合作为最后兜底逻辑,避免服务直接崩溃。
  4. 对于路由之外的异步后台任务抛出的异常,可以统一为异步任务包装CATCH块,或在全局调度器层面配置异常处理。

内容的提问来源于stack exchange,提问作者user13195651

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 13:48:03