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

io.sentry.core.SentryExceptionFactory Maven / Gradle / Ivy

There is a newer version: 3.0.0-alpha.1
Show newest version
package io.sentry.core;

import io.sentry.core.exception.ExceptionMechanismException;
import io.sentry.core.protocol.Mechanism;
import io.sentry.core.protocol.SentryException;
import io.sentry.core.protocol.SentryStackTrace;
import io.sentry.core.util.Objects;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

/** class responsible for converting Java Throwable to SentryExceptions */
final class SentryExceptionFactory {

  /** the SentryStackTraceFactory */
  private final @NotNull SentryStackTraceFactory sentryStackTraceFactory;

  /**
   * ctor SentryExceptionFactory
   *
   * @param sentryStackTraceFactory the sentryStackTraceFactory
   */
  public SentryExceptionFactory(final @NotNull SentryStackTraceFactory sentryStackTraceFactory) {
    this.sentryStackTraceFactory =
        Objects.requireNonNull(sentryStackTraceFactory, "The SentryStackTraceFactory is required.");
  }

  /**
   * Creates a new instance from the given {@code throwable}.
   *
   * @param throwable the {@link Throwable} to build this instance from
   */
  @NotNull
  List getSentryExceptions(final @NotNull Throwable throwable) {
    return getSentryExceptions(extractExceptionQueue(throwable));
  }

  /**
   * Creates a new instance from the given {@code exceptions}.
   *
   * @param exceptions a {@link Deque} of {@link SentryException} to build this instance from
   */
  private @NotNull List getSentryExceptions(
      final @NotNull Deque exceptions) {
    return new ArrayList<>(exceptions);
  }

  /**
   * Creates a Sentry exception based on a Java Throwable.
   *
   * 

The {@code childExceptionStackTrace} parameter is used to define the common frames with the * child exception (Exception caused by {@code throwable}). * * @param throwable Java exception to send to Sentry. * @param exceptionMechanism The optional {@link Mechanism} of the {@code throwable}. Or null if * none exist. * @param thread The optional {@link Thread} which the exception originated. Or null if not known. */ private @NotNull SentryException getSentryException( @NotNull final Throwable throwable, @Nullable final Mechanism exceptionMechanism, @Nullable final Thread thread) { final Package exceptionPackage = throwable.getClass().getPackage(); final String fullClassName = throwable.getClass().getName(); final SentryException exception = new SentryException(); final String exceptionMessage = throwable.getMessage(); final String exceptionClassName = exceptionPackage != null ? fullClassName.replace(exceptionPackage.getName() + ".", "") : fullClassName; final String exceptionPackageName = exceptionPackage != null ? exceptionPackage.getName() : null; final SentryStackTrace sentryStackTrace = new SentryStackTrace(); sentryStackTrace.setFrames(sentryStackTraceFactory.getStackFrames(throwable.getStackTrace())); if (thread != null) { exception.setThreadId(thread.getId()); } exception.setStacktrace(sentryStackTrace); exception.setType(exceptionClassName); exception.setMechanism(exceptionMechanism); exception.setModule(exceptionPackageName); exception.setValue(exceptionMessage); return exception; } /** * Transforms a {@link Throwable} into a Queue of {@link SentryException}. * *

Multiple values represent chained exceptions and should be sorted oldest to newest. * * @param throwable throwable to transform in a queue of exceptions. * @return a queue of exception with StackTrace. */ @TestOnly @NotNull Deque extractExceptionQueue(final @NotNull Throwable throwable) { final Deque exceptions = new ArrayDeque<>(); final Set circularityDetector = new HashSet<>(); Mechanism exceptionMechanism; Thread thread; Throwable currentThrowable = throwable; // Stack the exceptions to send them in the reverse order while (currentThrowable != null && circularityDetector.add(currentThrowable)) { if (currentThrowable instanceof ExceptionMechanismException) { // this is for ANR I believe ExceptionMechanismException exceptionMechanismThrowable = (ExceptionMechanismException) currentThrowable; exceptionMechanism = exceptionMechanismThrowable.getExceptionMechanism(); currentThrowable = exceptionMechanismThrowable.getThrowable(); thread = exceptionMechanismThrowable.getThread(); } else { exceptionMechanism = null; thread = Thread.currentThread(); } SentryException exception = getSentryException(currentThrowable, exceptionMechanism, thread); exceptions.addFirst(exception); currentThrowable = currentThrowable.getCause(); } return exceptions; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy