public T withException()

in instrumentation/src/main/java/com/uber/data/kafka/instrumentation/Instrumentation.java [147:198]


  public <T, E extends Exception> T withException(
      Logger logger,
      Scope scope,
      @Nullable Tracer tracer,
      ThrowingSupplier<T, E> supplier,
      Function<T, Boolean> resultChecker,
      String name,
      String... tags)
      throws E {
    @Nullable Span span = null;
    if (tracer != null) {
      Span parentSpan = tracer.activeSpan();
      span = startSpan(tracer, parentSpan, name);
    }
    long startNs = System.nanoTime();
    boolean isFailure = false;
    Closeable tracing = getTracingScope(tracer, span);
    try {
      T t = supplier.get();
      try {
        boolean success = resultChecker.apply(t);
        if (!success) {
          logAndMetricsFailure(logger, scope, System.nanoTime() - startNs, name, tags);
          isFailure = true;
        }
      } catch (Throwable ignored) {
        // treats exception as success, so we don't set isFailure.
      }
      return t;
    } catch (RuntimeException | Error e) {
      isFailure = true;
      logAndMetricsFailure(logger, scope, e, System.nanoTime() - startNs, name, tags);
      throw e;
    } catch (Exception ex) {
      isFailure = true;
      // supplier can only return type E for checked exception so we can safely cast to E.
      @SuppressWarnings("unchecked")
      E e = (E) ex;
      logAndMetricsFailure(logger, scope, e, System.nanoTime() - startNs, name, tags);
      throw e;
    } finally {
      if (!isFailure) {
        logAndMetricsSuccess(logger, scope, System.nanoTime() - startNs, name, tags);
      }
      // tracing implements Closeable interface which may throw IOException, but
      // the actual implementation of tracer scope never throws IOException so we can use safeClose.
      safeClose(tracing);
      if (span != null) {
        span.finish();
      }
    }
  }