问题描述
我是 quarkus/resteasy 的新手,但是当我在开发模式下本地运行我的 quarkus 应用程序时,未处理的异常包括有用的详细信息和堆栈跟踪,如下所示:
{
"details": "Error handling b4f19eef-3634-49f4-865e-55ee75ee3f82-1,org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException: bla bla bla...","stack": "org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException: Cannot invoke ...
... mile long stack trace here ..."
}
但是,从服务器运行,我收到了这些精简的错误消息,如下所示:
{
"details": "Error id e7bdec12-e36c-40fe-a7c6-096ec8eb62ca-4","stack": ""
}
如何像从服务器本地获取那样获取异常消息?是什么导致了这种变化?我找不到任何可能与此相关的 application.properties
(https://quarkus.io/guides/all-config),而且我不确定还能在哪里查看。
解决方法
正如 Geoand 所提到的,除了本地开发环境之外,您真的不想在任何其他环境上执行此操作。然而,JaxRS(Resteasy 的 impl)为您提供了完全的控制权,您可以创建自定义的 JaxRS 异常映射器,将未处理的异常转换为您想要的任何 HTTP 响应,包括堆栈跟踪的所有血腥细节。示例:
@Provider
@Priority(10000)
//the more generic the mapper,the lower its prio should be(the lower the number the higher the pri),so you can override it with more specific mappers
public class ChattyExceptionMapper implements ExceptionMapper<Exception> {
@Context
HttpHeaders headers;
//you can inject all JaxRS ctx data using @Context,see spec
@Context
ResourceInfo resourceInfo;
@Override
public Response toResponse(Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
return Response
.serverError()
.entity(Map.of(
"requestHeaders",headers.getRequestHeaders(),"endpointClass",resourceInfo.getResourceClass(),"endpointMethod",resourceInfo.getResourceMethod().getName(),"stacktrace",sw.toString()))
.build();
}
}
我在 prod 中更有用的方法可能是,您在后台向某些错误报告系统(例如 Sentry,...)报告堆栈跟踪/错误信息,为该事件分配一些 ID 并在您的错误响应(通过您的自定义异常映射器)。通过这种方式,您可以在收到客户/客户的投诉之前主动监控错误,如果这样做,您可以将 eventId 与错误报告系统中的所有详细数据相关联。
,Quarkus 是故意这样做的。
在开发模式下,当您正在开发应用程序时,您希望拥有您可以获得的所有信息。 但是,在生产模式下,您不想将应用程序的内部结构泄露给调用者。 所以在这种情况下,你只能看到服务器日志上的堆栈跟踪