All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lognet.springboot.grpc.FailureHandlingSupport Maven / Gradle / Ivy

The newest version!
// Generated by delombok at Wed Sep 27 05:27:18 UTC 2023
package org.lognet.springboot.grpc;

import static org.lognet.springboot.grpc.recovery.GRpcExceptionHandlerInterceptor.EXCEPTION_HANDLED;

import io.grpc.*;
import java.util.Optional;
import java.util.function.Consumer;
import org.lognet.springboot.grpc.recovery.GRpcExceptionHandlerMethodResolver;
import org.lognet.springboot.grpc.recovery.GRpcExceptionScope;
import org.lognet.springboot.grpc.recovery.GRpcRuntimeExceptionWrapper;
import org.lognet.springboot.grpc.recovery.HandlerMethod;

public class FailureHandlingSupport {
  @java.lang.SuppressWarnings("all")
  private static final org.slf4j.Logger log =
      org.slf4j.LoggerFactory.getLogger(FailureHandlingSupport.class);

  private final GRpcExceptionHandlerMethodResolver methodResolver;

  public FailureHandlingSupport(GRpcExceptionHandlerMethodResolver methodResolver) {
    this.methodResolver = methodResolver;
  }

  public void closeCall(Exception e, ServerCall call, Metadata headers)
      throws RuntimeException {
    closeCall(e, call, headers, null);
  }

  public void closeCall(
      Exception e,
      ServerCall call,
      Metadata headers,
      Consumer customizer)
      throws RuntimeException {
    Optional.ofNullable(EXCEPTION_HANDLED.get()).ifPresent(h -> h.set(true));
    if (e == null) {
      log.warn("Closing null exception with {}", Status.INTERNAL);
      call.close(Status.INTERNAL, new Metadata());
    } else {
      Throwable unwrapped = GRpcRuntimeExceptionWrapper.unwrap(e);
      final Optional handlerMethod =
          methodResolver.resolveMethodByThrowable(
              call.getMethodDescriptor().getServiceName(), unwrapped);
      if (handlerMethod.isPresent()) {
        handle(handlerMethod.get(), call, customizer, e, headers, unwrapped);
      } else if (unwrapped instanceof StatusRuntimeException
          || unwrapped instanceof StatusException) {
        Status status =
            unwrapped instanceof StatusRuntimeException
                ? ((StatusRuntimeException) unwrapped).getStatus()
                : ((StatusException) unwrapped).getStatus();
        Metadata metadata =
            unwrapped instanceof StatusRuntimeException
                ? ((StatusRuntimeException) unwrapped).getTrailers()
                : ((StatusException) unwrapped).getTrailers();
        log.warn("Closing call with {}", status);
        call.close(status, Optional.ofNullable(metadata).orElseGet(Metadata::new));
      } else {
        log.warn("Closing call with {}", Status.INTERNAL);
        call.close(Status.INTERNAL, new Metadata());
      }
    }
  }

  private void handle(
      HandlerMethod handler,
      ServerCall call,
      Consumer customizer,
      Exception e,
      Metadata headers,
      Throwable unwrapped) {
    final GRpcExceptionScope.GRpcExceptionScopeBuilder exceptionScopeBuilder =
        GRpcExceptionScope.builder()
            .callHeaders(headers)
            .methodCallAttributes(call.getAttributes())
            .methodDescriptor(call.getMethodDescriptor())
            .hint(GRpcRuntimeExceptionWrapper.getHint(e));
    if (customizer != null) {
      customizer.accept(exceptionScopeBuilder);
    }
    final GRpcExceptionScope excScope = exceptionScopeBuilder.build();
    try {
      Status statusToSend = handler.invoke(unwrapped, excScope);
      Metadata metadataToSend = excScope.getResponseHeaders();
      log.warn(
          "Handled exception {} call as {}", unwrapped.getClass().getSimpleName(), statusToSend);
      call.close(statusToSend, Optional.ofNullable(metadataToSend).orElseGet(Metadata::new));
    } catch (Exception handlerException) {
      log.error(
          "Caught exception while handling exception {} using method {}, closing with {}.",
          unwrapped.getClass().getSimpleName(),
          handler.getMethod(),
          Status.INTERNAL,
          handlerException);
      call.close(Status.INTERNAL, new Metadata());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy