Spring Webflux CoRouter中onError及全局上下文失效问题咨询
Kotlin协程WebFlux中Micrometer链路追踪上下文问题解决
一、onError逻辑中上下文失效的处理
Kotlin协程WebFlux里,错误处理逻辑默认不会自动继承上游的协程Context,需要手动将当前上下文传入错误处理块:
- 在
onErrorResume、onErrorReturn等错误操作中,用withContext(coroutineContext)包裹处理逻辑,确保MdcContext能被访问到。示例代码:
coRouter { GET("/demo") { req -> demoHandler.demoCall(req) .onErrorResume { ex -> withContext(coroutineContext) { // 这里可以正常访问MdcContext中的链路追踪信息 logger.error("请求失败", ex) ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).bodyValue("error") } } }.context { ctx -> // 配置MdcContext ctx.put(MdcContext.of(TraceContext.current())) } }
二、全局生效上下文的配置方案
如果在父nest或coRouter根节点配置Context后,子handler丢失上下文,是因为直接传递方法引用会脱离当前协程作用域,可通过以下两种方式解决:
方式1:全局过滤器注入上下文
定义CoroutineWebFilter全局拦截所有请求,在过滤器层面设置MdcContext,确保整个请求链路都携带上下文:
@Component class TraceContextFilter : CoroutineWebFilter { override suspend fun filter(exchange: ServerWebExchange, chain: CoroutineWebFilterChain): ServerResponse { val traceContext = TraceContext.current() return withContext(MdcContext.of(traceContext)) { chain.filter(exchange) } } }
这种方式不需要在路由中单独配置context,所有请求的协程链路都会自动携带MdcContext,包括handler和错误处理逻辑。
方式2:路由层级确保上下文继承
如果必须在路由层面配置,不要直接传递handler方法引用,而是在coHandler中显式通过withContext继承当前协程Context:
coRouter { context { ctx -> ctx.put(MdcContext.of(TraceContext.current())) } GET("/demo") { req -> withContext(coroutineContext) { demoHandler.demoCall(req) } } // 嵌套路由同理 nest(path("/api")) { GET("/test") { req -> withContext(coroutineContext) { demoHandler.testCall(req) } } } }
这样每个handler的调用都处于当前协程Context的作用域内,不会丢失链路追踪信息。
内容的提问来源于stack exchange,提问作者meberhard
相关产品推荐
相关产品推荐

