echo中panic需用recover中间件拦截,否则连接静默断开;启用时须首个注册、置于路由前;自定义需用recoverwithwriter或手动响应;子goroutine panic须单独recover。

在Echo框架中,panic会导致HTTP连接静默断开、无响应、无日志、前端收不到任何错误体,必须通过Recover中间件显式拦截才能转为结构化HTTP错误返回。
启用默认Recover中间件
第一步:在Echo实例初始化后、注册路由前,调用e.Use(middleware.Recover());这一步必须放在所有业务中间件和路由注册之前,否则panic可能在Recover执行前就已逃逸出goroutine上下文。
第二步:确保middleware.Recover()是第一个被e.Use()注册的中间件——若前置注册了JWT验证、BasicAuth等中间件,它们内部发生的panic将无法被捕获,因为Recover只包裹后续c.Next()调用链。
第三步:启动服务后,任意handler内触发panic(如panic("test")或空指针解引用),Echo会自动返回HTTP 500响应,并在标准错误日志中输出panic值和堆栈(前提是server.ErrorLog已正确配置)。
自定义Recover行为
方法一:替换默认panic处理逻辑
创建自定义Recover中间件,传入函数处理panic值:middleware.RecoverWithWriter(os.Stdout, func(c echo.Context, err interface{}) { /* 自定义日志+上报 */ })。注意该函数不负责写HTTP响应,仅用于副作用处理;响应仍由Echo内部默认逻辑完成。
诊断并恢复通过 SSH 隧道连接的 OpenClaw 节点。用于解决配对必需错误、隧道冲突、远程端点错误以及 SSH 目标配置错误等问题。
方法二:结合HTTPErrorHandler统一输出格式
在e.HTTPErrorHandler = func(err error, c echo.Context) { ... }中判断err是否为*echo.HTTPError或panic包装后的错误;但【Recover中间件本身不触发HTTPErrorHandler】,它直接终止请求并返回500,因此必须在Recover回调函数里手动调用c.JSON()或c.String()才能输出自定义结构体。
捕获子goroutine panic
Recover中间件只对主请求goroutine生效,handler内起的go func() { ... }()中panic完全不可见。
必须为每个子goroutine单独加defer func(){ if r := recover(); r != nil { log.Printf("sub-goroutine panic: %v", r) } }()——漏掉任意一个,panic就会导致连接无声断开、MQ消息丢失、定时任务静默退出。
推荐封装safeGo()工具函数,在项目全局复用,避免重复手写defer+recover模板。










