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

在Scala中运行http4s服务器时如何在控制台记录非致命错误

解决http4s运行时错误无日志、返回通用500的问题

一、通过Logback配置开启错误日志输出

http4s默认会将请求处理中的错误信息归属到org.http4s日志类别下,你只需调整该类别的日志级别,就能让错误实时显示在控制台:

  1. 创建或修改src/main/resources/logback.xml,添加以下配置:
<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex</pattern>
    </encoder>
  </appender>

  <!-- 开启http4s核心错误日志,%ex会打印完整异常栈追踪 -->
  <logger name="org.http4s" level="ERROR"/>
  <!-- 若需要查看完整请求处理流程,可将级别改为DEBUG -->
  <!-- <logger name="org.http4s" level="DEBUG"/> -->

  <root level="INFO">
    <appender-ref ref="CONSOLE"/>
  </root>
</configuration>

二、自定义http4s错误处理中间件

如果Logback配置后仍有业务层错误未被捕获,说明默认错误处理逻辑可能吞掉了异常,需要手动添加中间件确保所有异常被记录:

以Scala代码为例:

import org.http4s._
import org.http4s.dsl.io._
import org.http4s.server._
import org.slf4j.LoggerFactory
import cats.effect.IO

// 初始化业务日志实例
val serverLogger = LoggerFactory.getLogger("ApiServer")

// 自定义错误处理路由
val customErrorHandler: HttpRoutes[IO] = HttpRoutes.of[IO] {
  case request =>
    // 从请求属性中获取抛出的异常
    val errorOpt = request.attributes.lookup(RequestKeys.Throwable)
    errorOpt.foreach { err =>
      // 打印错误详情:请求方法、路径、异常栈追踪
      serverLogger.error(s"处理请求 ${request.method} ${request.uri} 失败", err)
    }
    InternalServerError("服务器内部错误")
}

// 假设这是你已有的业务路由
val yourApiRoutes: HttpRoutes[IO] = Router(
  "/users" -> userRoutes,
  "/posts" -> postRoutes
).orNotFound

// 最终HttpApp,确保所有异常经过错误处理
val app: HttpApp[IO] = yourApiRoutes.handleErrorWith(customErrorHandler)

该中间件会捕获所有未处理的异常,打印完整栈追踪后返回500响应,彻底解决"吞错误"问题。

三、确保业务逻辑的异常传递

业务代码(如数据库请求、Circe编码)中的异常需通过IO的raiseError抛出,而非手动吞掉:

// 错误示例:吞掉异常,http4s无法捕获
def fetchUser(id: Long): IO[User] = 
  db.run(sql"select * from users where id = $id".as[User])
    .handleError(_ => IO.pure(User.empty))

// 正确示例:让异常自然向上传递,被http4s捕获
def fetchUser(id: Long): IO[User] = 
  db.run(sql"select * from users where id = $id".as[User])

IDE配置注意事项

多数IDE(如IntelliJ IDEA)默认输出所有级别日志,只需确保Run/Debug配置未过滤ERROR或DEBUG级别的日志。若日志仍不显示,检查控制台面板的过滤规则,移除不必要的级别限制。

内容的提问来源于stack exchange,提问作者Gabriel Santana Paredes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:05:29