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

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

There is a newer version: 5.1.5
Show newest version
// Generated by delombok at Mon Jul 31 05:34:41 UTC 2023
package org.lognet.springboot.grpc;

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

import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
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(RuntimeException e, ServerCall call, Metadata headers)
      throws RuntimeException {
    closeCall(e, call, headers, null);
  }

  public void closeCall(
      RuntimeException 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) {
        StatusRuntimeException sre = (StatusRuntimeException) unwrapped;
        log.warn("Closing call with {}", sre.getStatus());
        call.close(
            sre.getStatus(), Optional.ofNullable(sre.getTrailers()).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,
      RuntimeException 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 - 2025 Weber Informatics LLC | Privacy Policy