diff --git a/src/main/kotlin/top/lolosia/web/interceptor/ErrorWebFilter.kt b/src/main/kotlin/top/lolosia/web/interceptor/ErrorWebFilter.kt index ece5eb5..b71315d 100644 --- a/src/main/kotlin/top/lolosia/web/interceptor/ErrorWebFilter.kt +++ b/src/main/kotlin/top/lolosia/web/interceptor/ErrorWebFilter.kt @@ -2,6 +2,7 @@ package top.lolosia.web.interceptor import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.NullNode +import kotlinx.coroutines.isActive import top.lolosia.web.util.bundle.bundleScope import top.lolosia.web.util.kotlin.pass import kotlinx.coroutines.reactor.awaitSingleOrNull @@ -48,7 +49,9 @@ class ErrorWebFilter : OrderedWebFilter { else if (e::class.qualifiedName == "kotlinx.coroutines.JobCancellationException") pass else logger.error(e.message, e) - if (exchange.response.isCommitted) return@mono + // 如果响应体被提交,或者连接被切断,直接返回 + if (exchange.response.isCommitted || !isActive) return@mono + val obj = bundleScope { "data" set NullNode.instance diff --git a/src/main/kotlin/top/lolosia/web/interceptor/LogWebFilter.kt b/src/main/kotlin/top/lolosia/web/interceptor/LogWebFilter.kt index 19114fa..3d4dc90 100644 --- a/src/main/kotlin/top/lolosia/web/interceptor/LogWebFilter.kt +++ b/src/main/kotlin/top/lolosia/web/interceptor/LogWebFilter.kt @@ -62,7 +62,8 @@ class LogWebFilter : OrderedWebFilter, CoroutineScope { fun time(s: Long) = if (s < 10000) String.format("%4dms", s) else String.format("%5ds", s / 1000) // 请求处理步骤 - val reqJob = launch { + // 防止被客户端断开连接而意外取消日志记录器 + val reqJob = CoroutineScope(NonCancellable).launch { try { val f = suspend { var bytes: ByteArray? = null @@ -76,7 +77,7 @@ class LogWebFilter : OrderedWebFilter, CoroutineScope { if (str.length > 200) str = str.s200() logger.value.info("$up $str") } - if (url.startsWith("/api/")) f() + if (url.startsWith("/home/api/")) f() else writeInfo = f } catch (_: Throwable) { } @@ -102,24 +103,27 @@ class LogWebFilter : OrderedWebFilter, CoroutineScope { if (e is HttpStatusCodeException) code = e.statusCode.value() throw e } finally { - val f = suspend { - // 响应处理步骤 - val length = data.length - if (length > 200) data = data.s200() - val end1 = System.currentTimeMillis() - // 消费掉请求体,避免由于空请求体导致下方的方法死锁。 - request.consume() - // 等待请求处理完成 - reqJob.join() - if (code in 200 until 400) { - logger.value.info("$down${time(end1 - start)}$end $data") - } else { - writeInfo?.let { it() } - logger.value.warn("$err0 \u001B[1;30;43m $code $err1 $data $end") + // 避免因客户端断开连接而捕获不到信息 + CoroutineScope(NonCancellable).launch { + val f = suspend { + // 响应处理步骤 + val length = data.length + if (length > 200) data = data.s200() + val end1 = System.currentTimeMillis() + // 消费掉请求体,避免由于空请求体导致下方的方法死锁。 + request.consume() + // 等待请求处理完成 + reqJob.join() + if (code in 200 until 400) { + logger.value.info("$down${time(end1 - start)}$end $data") + } else { + writeInfo?.let { it() } + logger.value.warn("$err0 \u001B[1;30;43m $code $err1 $data $end") + } } + if (url.startsWith("/home/api/")) f() + else if (code !in 200 until 400) f() } - if (url.startsWith("/api/")) f() - else if (code !in 200 until 400) f() } }.then() }