Ответ 1
Если вы посмотрите на класс SentryExceptionResolver
public class SentryExceptionResolver implements HandlerExceptionResolver, Ordered {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
Sentry.capture(ex);
// null = run other HandlerExceptionResolvers to actually handle the exception
return null;
}
@Override
public int getOrder() {
// ensure this resolver runs first so that all exceptions are reported
return Integer.MIN_VALUE;
}
}
Возвращая Integer.MIN_VALUE
в getOrder
он гарантирует, что он будет вызван первым. Даже если вы установили Priority
в 1
, это не сработает. Поэтому вы хотите изменить свою
@Configuration
public class FactoryBeanAppConfig {
@Bean
public HandlerExceptionResolver sentryExceptionResolver() {
return new SentryExceptionResolver();
}
@Bean
public ServletContextInitializer sentryServletContextInitializer() {
return new SentryServletContextInitializer();
}
}
в
@Configuration
public class FactoryBeanAppConfig {
@Bean
public HandlerExceptionResolver sentryExceptionResolver() {
return new SentryExceptionResolver() {
@Override
public int getOrder() {
// ensure we can get some resolver earlier than this
return 10;
}
};
}
@Bean
public ServletContextInitializer sentryServletContextInitializer() {
return new SentryServletContextInitializer();
}
}
Это гарантирует, что ваш обработчик может быть запущен раньше. В вашем коде цикл для rootCause
неверен
while (ex.getCause() != null) {
rootCause = ex.getCause();
}
Это бесконечный цикл, поскольку вы использовали ex
вместо rootCause
. Даже если вы его исправите, он все равно может стать бесконечным циклом. Когда причина исключения вернется сама, она застрянет. Я не проверил его полностью, но считаю, что это должно быть как ниже
while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
rootCause = rootCause.getCause();
}
Это один из способов решения вашей проблемы. Но вам нужно отправить исключение самостоятельно в Sentry. Таким образом, есть еще один способ справиться с вашим требованием
Путь 2
В этом случае вы можете выполнить всю логику в своей Конфигурации и изменить ее ниже
@Configuration
public class FactoryBeanAppConfig {
@Bean
public HandlerExceptionResolver sentryExceptionResolver() {
return new SentryExceptionResolver() {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
Throwable rootCause = ex;
while (rootCause .getCause() != null && rootCause.getCause() != rootCause) {
rootCause = rootCause.getCause();
}
if (!rootCause.getMessage().contains("Broken pipe")) {
super.resolveException(request, response, handler, ex);
}
return null;
}
};
}
@Bean
public ServletContextInitializer sentryServletContextInitializer() {
return new SentryServletContextInitializer();
}
}