首页 > 解决方案 > 如何在过滤器的错误处理中连接到 micronaut 服务器?

问题描述

对于我的 micronaut 服务器发出的任何 4xx 或 5xx 响应,我想记录响应状态代码和它所针对的端点。看起来过滤器是一个很好的地方,但我似乎无法弄清楚如何插入 onError 处理

例如,这个过滤器

@Filter("/**")
class RequestLoggerFilter: OncePerRequestHttpServerFilter() {
  companion object {
    private val log = LogManager.getLogger(RequestLoggerFilter::class.java)
  }

  override fun doFilterOnce(request: HttpRequest<*>, chain: ServerFilterChain): Publisher<MutableHttpResponse<*>>? {
    return Publishers.then(chain.proceed(request), ResponseLogger(request))
  }

  class ResponseLogger(private val request: HttpRequest<*>): Consumer<MutableHttpResponse<*>> {
    override fun accept(response: MutableHttpResponse<*>) {
      log.info("Status: ${response.status.code} Endpoint: ${request.path}")
    }
  }
}

仅记录成功响应,而不记录 4xx 或 5xx 响应。我怎样才能让它挂钩到 onError 处理?

标签: kotlinmicronaut

解决方案


您可以执行以下操作。创建您自己的 ApplicationException(扩展 RuntimeException),您可以在那里处理您的应用程序错误,特别是它们如何导致 http 错误代码。您的异常也可以保存状态代码。

例子:

class BadRequestException extends ApplicationException {
 
    public HttpStatus getStatus() {
        return HttpStatus.BAD_REQUEST;
    }
}

您可以有多个此 ExceptionHandler 用于不同的目的。

@Slf4j
@Produces
@Singleton
@Requires(classes = {ApplicationException.class, ExceptionHandler.class})
public class ApplicationExceptionHandler implements ExceptionHandler<ApplicationException, HttpResponse> {

    @Override
    public HttpResponse handle(final HttpRequest request, final ApplicationException exception) {
        log.error("Application exception message={}, cause={}", exception.getMessage(), exception.getCause());
        final String message = exception.getMessage();
        final String code = exception.getClass().getSimpleName();
        final ErrorCode error = new ErrorCode(message, code);

        log.info("Status: ${exception.getStatus())} Endpoint: ${request.path}")

        return HttpResponse.status(exception.getStatus()).body(error);
    }
}

推荐阅读