diff --git a/bugsnag-android-core/api/bugsnag-android-core.api b/bugsnag-android-core/api/bugsnag-android-core.api
index 3509b235bd..211ce1691e 100644
--- a/bugsnag-android-core/api/bugsnag-android-core.api
+++ b/bugsnag-android-core/api/bugsnag-android-core.api
@@ -347,7 +347,9 @@ public final class com/bugsnag/android/ErrorTypes {
public final fun setUnhandledRejections (Z)V
}
-public class com/bugsnag/android/Event : com/bugsnag/android/FeatureFlagAware, com/bugsnag/android/JsonStream$Streamable, com/bugsnag/android/MetadataAware, com/bugsnag/android/UserAware {
+public final class com/bugsnag/android/Event : com/bugsnag/android/FeatureFlagAware, com/bugsnag/android/JsonStream$Streamable, com/bugsnag/android/MetadataAware, com/bugsnag/android/UserAware {
+ public field app Lcom/bugsnag/android/AppWithState;
+ public field device Lcom/bugsnag/android/DeviceWithState;
public fun addFeatureFlag (Ljava/lang/String;)V
public fun addFeatureFlag (Ljava/lang/String;Ljava/lang/String;)V
public fun addFeatureFlags (Ljava/lang/Iterable;)V
@@ -357,31 +359,48 @@ public class com/bugsnag/android/Event : com/bugsnag/android/FeatureFlagAware, c
public fun clearFeatureFlags ()V
public fun clearMetadata (Ljava/lang/String;)V
public fun clearMetadata (Ljava/lang/String;Ljava/lang/String;)V
- public fun getApiKey ()Ljava/lang/String;
- public fun getApp ()Lcom/bugsnag/android/AppWithState;
- public fun getBreadcrumbs ()Ljava/util/List;
- public fun getContext ()Ljava/lang/String;
- public fun getDevice ()Lcom/bugsnag/android/DeviceWithState;
- public fun getErrors ()Ljava/util/List;
- public fun getFeatureFlags ()Ljava/util/List;
- public fun getGroupingHash ()Ljava/lang/String;
+ public final fun getApiKey ()Ljava/lang/String;
+ public final fun getApp ()Lcom/bugsnag/android/AppWithState;
+ public final fun getBreadcrumbs ()Ljava/util/List;
+ public final fun getContext ()Ljava/lang/String;
+ public final fun getDevice ()Lcom/bugsnag/android/DeviceWithState;
+ public final fun getErrors ()Ljava/util/List;
+ public final fun getFeatureFlags ()Ljava/util/List;
+ public final fun getGroupingHash ()Ljava/lang/String;
+ public final fun getInternalMetrics ()Lcom/bugsnag/android/internal/InternalMetrics;
+ public final fun getLogger ()Lcom/bugsnag/android/Logger;
public fun getMetadata (Ljava/lang/String;)Ljava/util/Map;
public fun getMetadata (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
- public fun getOriginalError ()Ljava/lang/Throwable;
- public fun getSeverity ()Lcom/bugsnag/android/Severity;
- public fun getThreads ()Ljava/util/List;
+ public final fun getOriginalError ()Ljava/lang/Throwable;
+ public final fun getOriginalUnhandled ()Z
+ public final fun getRedactedKeys ()Ljava/util/Collection;
+ public final fun getSession ()Lcom/bugsnag/android/Session;
+ public final fun getSeverity ()Lcom/bugsnag/android/Severity;
+ public final fun getSeverityReasonType ()Ljava/lang/String;
+ public final fun getThreads ()Ljava/util/List;
+ public final fun getUnhandledOverridden ()Z
public fun getUser ()Lcom/bugsnag/android/User;
- public fun isUnhandled ()Z
- public fun setApiKey (Ljava/lang/String;)V
- public fun setContext (Ljava/lang/String;)V
- public fun setGroupingHash (Ljava/lang/String;)V
- public fun setSeverity (Lcom/bugsnag/android/Severity;)V
- public fun setUnhandled (Z)V
+ public final fun getUserImpl ()Lcom/bugsnag/android/User;
+ public final fun isUnhandled ()Z
+ public final fun setApiKey (Ljava/lang/String;)V
+ public final fun setApp (Lcom/bugsnag/android/AppWithState;)V
+ public final fun setBreadcrumbs (Ljava/util/List;)V
+ public final fun setContext (Ljava/lang/String;)V
+ public final fun setDevice (Lcom/bugsnag/android/DeviceWithState;)V
+ public final fun setErrors (Ljava/util/List;)V
+ public final fun setGroupingHash (Ljava/lang/String;)V
+ public final fun setInternalMetrics (Lcom/bugsnag/android/internal/InternalMetrics;)V
+ public final fun setRedactedKeys (Ljava/util/Collection;)V
+ public final fun setSession (Lcom/bugsnag/android/Session;)V
+ public final fun setSeverity (Lcom/bugsnag/android/Severity;)V
+ public final fun setThreads (Ljava/util/List;)V
+ public final fun setUnhandled (Z)V
public fun setUser (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
- protected fun shouldDiscardClass ()Z
+ public final fun setUserImpl (Lcom/bugsnag/android/User;)V
+ public final fun shouldDiscardClass ()Z
public fun toStream (Lcom/bugsnag/android/JsonStream;)V
- protected fun updateSeverityInternal (Lcom/bugsnag/android/Severity;)V
- protected fun updateSeverityReason (Ljava/lang/String;)V
+ public final fun updateSeverityInternal (Lcom/bugsnag/android/Severity;)V
+ public final fun updateSeverityReason (Ljava/lang/String;)V
}
public final class com/bugsnag/android/EventPayload : com/bugsnag/android/JsonStream$Streamable {
diff --git a/bugsnag-android-core/detekt-baseline.xml b/bugsnag-android-core/detekt-baseline.xml
index bccf015f28..9f40db82ff 100644
--- a/bugsnag-android-core/detekt-baseline.xml
+++ b/bugsnag-android-core/detekt-baseline.xml
@@ -14,8 +14,8 @@
LongParameterList:DeviceDataCollector.kt$DeviceDataCollector$( private val connectivity: Connectivity, private val appContext: Context, resources: Resources, private val deviceId: String?, private val internalDeviceId: String?, private val buildInfo: DeviceBuildInfo, private val dataDirectory: File, rootDetector: RootDetector, private val bgTaskService: BackgroundTaskService, private val logger: Logger )
LongParameterList:DeviceIdStore.kt$DeviceIdStore$( context: Context, deviceIdfile: File = File(context.filesDir, "device-id"), deviceIdGenerator: () -> UUID = { UUID.randomUUID() }, internalDeviceIdfile: File = File(context.filesDir, "internal-device-id"), internalDeviceIdGenerator: () -> UUID = { UUID.randomUUID() }, private val sharedPrefMigrator: SharedPrefMigrator, logger: Logger )
LongParameterList:DeviceWithState.kt$DeviceWithState$( buildInfo: DeviceBuildInfo, jailbroken: Boolean?, id: String?, locale: String?, totalMemory: Long?, runtimeVersions: MutableMap<String, Any>, /** * The number of free bytes of storage available on the device */ var freeDisk: Long?, /** * The number of free bytes of memory available on the device */ var freeMemory: Long?, /** * The orientation of the device when the event occurred: either portrait or landscape */ var orientation: String?, /** * The timestamp on the device when the event occurred */ var time: Date? )
+ LongParameterList:Event.kt$Event$( apiKey: String, logger: Logger, breadcrumbs: MutableList<Breadcrumb> = mutableListOf(), discardClasses: Set<Pattern> = setOf(), errors: MutableList<Error> = mutableListOf(), metadata: Metadata = Metadata(), featureFlags: FeatureFlags = FeatureFlags(), originalError: Throwable? = null, projectPackages: Collection<String> = setOf(), severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION), threads: MutableList<Thread> = mutableListOf(), user: User = User(), redactionKeys: Set<Pattern>? = null )
LongParameterList:EventFilenameInfo.kt$EventFilenameInfo.Companion$( obj: Any, uuid: String = UUID.randomUUID().toString(), apiKey: String?, timestamp: Long = System.currentTimeMillis(), config: ImmutableConfig, isLaunching: Boolean? = null )
- LongParameterList:EventInternal.kt$EventInternal$( apiKey: String, logger: Logger, breadcrumbs: MutableList<Breadcrumb> = mutableListOf(), discardClasses: Set<Pattern> = setOf(), errors: MutableList<Error> = mutableListOf(), metadata: Metadata = Metadata(), featureFlags: FeatureFlags = FeatureFlags(), originalError: Throwable? = null, projectPackages: Collection<String> = setOf(), severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION), threads: MutableList<Thread> = mutableListOf(), user: User = User(), redactionKeys: Set<Pattern>? = null )
LongParameterList:EventStorageModule.kt$EventStorageModule$( contextModule: ContextModule, configModule: ConfigModule, dataCollectionModule: DataCollectionModule, bgTaskService: BackgroundTaskService, trackerModule: TrackerModule, systemServiceModule: SystemServiceModule, notifier: Notifier, callbackState: CallbackState )
LongParameterList:NativeStackframe.kt$NativeStackframe$( /** * The name of the method that was being executed */ var method: String?, /** * The location of the source file */ var file: String?, /** * The line number within the source file this stackframe refers to */ var lineNumber: Number?, /** * The address of the instruction where the event occurred. */ var frameAddress: Long?, /** * The address of the function where the event occurred. */ var symbolAddress: Long?, /** * The address of the library where the event occurred. */ var loadAddress: Long?, /** * Whether this frame identifies the program counter */ var isPC: Boolean?, /** * The type of the error */ var type: ErrorType? = null, /** * Identifies the exact build this frame originates from. */ var codeIdentifier: String? = null, )
LongParameterList:StateEvent.kt$StateEvent.Install$( @JvmField val apiKey: String, @JvmField val autoDetectNdkCrashes: Boolean, @JvmField val appVersion: String?, @JvmField val buildUuid: String?, @JvmField val releaseStage: String?, @JvmField val lastRunInfoPath: String, @JvmField val consecutiveLaunchCrashes: Int, @JvmField val sendThreads: ThreadSendPolicy )
@@ -40,10 +40,7 @@
NestedBlockDepth:FileStore.kt$FileStore$fun findStoredFiles(): MutableList<File>
NestedBlockDepth:JsonHelper.kt$JsonHelper$fun jsonToLong(value: Any?): Long?
ProtectedMemberInFinalClass:ConfigInternal.kt$ConfigInternal$protected val plugins = HashSet<Plugin>()
- ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun isAnr(event: Event): Boolean
- ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun shouldDiscardClass(): Boolean
- ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun updateSeverityInternal(severity: Severity)
- ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun updateSeverityReason(@SeverityReason.SeverityReasonType reason: String)
+ ProtectedMemberInFinalClass:Event.kt$Event$protected fun isAnr(event: Event): Boolean
ReturnCount:DefaultDelivery.kt$DefaultDelivery$fun deliver( urlString: String, json: ByteArray, headers: Map<String, String?> ): DeliveryStatus
SpreadOperator:FileStore.kt$FileStore$(*listFiles)
SwallowedException:AppDataCollector.kt$AppDataCollector$e: Exception
@@ -64,7 +61,7 @@
ThrowsCount:JsonHelper.kt$JsonHelper$fun jsonToLong(value: Any?): Long?
TooManyFunctions:ConfigInternal.kt$ConfigInternal : CallbackAwareMetadataAwareUserAwareFeatureFlagAware
TooManyFunctions:DeviceDataCollector.kt$DeviceDataCollector
- TooManyFunctions:EventInternal.kt$EventInternal : FeatureFlagAwareStreamableMetadataAwareUserAware
+ TooManyFunctions:Event.kt$Event : StreamableMetadataAwareUserAwareFeatureFlagAware
UnusedPrivateProperty:ManifestConfigLoader.kt$ManifestConfigLoader.Companion$private const val LAUNCH_CRASH_THRESHOLD_MS = "$BUGSNAG_NS.LAUNCH_CRASH_THRESHOLD_MS"
UnusedPrivateProperty:ThreadStateTest.kt$ThreadStateTest$private val configuration = generateImmutableConfig()
UseCheckOrError:BackgroundTaskServiceTest.kt$BackgroundTaskServiceTest$throw IllegalStateException()
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/BugsnagEventMapper.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/BugsnagEventMapper.kt
index c8a7763932..4de2fed9ae 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/BugsnagEventMapper.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/BugsnagEventMapper.kt
@@ -13,12 +13,12 @@ internal class BugsnagEventMapper(
) {
internal fun convertToEvent(map: Map, apiKey: String): Event {
- return Event(convertToEventImpl(map, apiKey), logger)
+ return convertToEventImpl(map, apiKey)
}
@Suppress("UNCHECKED_CAST")
- internal fun convertToEventImpl(map: Map, apiKey: String): EventInternal {
- val event = EventInternal(apiKey, logger)
+ internal fun convertToEventImpl(map: Map, apiKey: String): Event {
+ val event = Event(apiKey, logger)
// populate exceptions. check this early to avoid unnecessary serialization if
// no stacktrace was gathered.
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/DefaultDelivery.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/DefaultDelivery.kt
index 72c8a9200f..3006e58a69 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/DefaultDelivery.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/DefaultDelivery.kt
@@ -44,8 +44,8 @@ internal class DefaultDelivery(
payload.apiKey = apiKey
}
- val (itemsTrimmed, dataTrimmed) = event.impl.trimMetadataStringsTo(maxStringValueLength)
- event.impl.internalMetrics.setMetadataTrimMetrics(
+ val (itemsTrimmed, dataTrimmed) = event.trimMetadataStringsTo(maxStringValueLength)
+ event.internalMetrics.setMetadataTrimMetrics(
itemsTrimmed,
dataTrimmed
)
@@ -56,8 +56,8 @@ internal class DefaultDelivery(
}
val breadcrumbAndBytesRemovedCounts =
- event.impl.trimBreadcrumbsBy(json.size - maxPayloadSize)
- event.impl.internalMetrics.setBreadcrumbTrimMetrics(
+ event.trimBreadcrumbsBy(json.size - maxPayloadSize)
+ event.internalMetrics.setBreadcrumbTrimMetrics(
breadcrumbAndBytesRemovedCounts.itemsTrimmed,
breadcrumbAndBytesRemovedCounts.dataTrimmed
)
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/DeliveryDelegate.java b/bugsnag-android-core/src/main/java/com/bugsnag/android/DeliveryDelegate.java
index 5c4ef01616..f79911b8f3 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/DeliveryDelegate.java
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/DeliveryDelegate.java
@@ -53,11 +53,11 @@ void deliver(@NonNull Event event) {
}
}
- if (event.getImpl().getOriginalUnhandled()) {
+ if (event.getOriginalUnhandled()) {
// should only send unhandled errors if they don't terminate the process (i.e. ANRs)
- String severityReasonType = event.getImpl().getSeverityReasonType();
+ String severityReasonType = event.getSeverityReasonType();
boolean promiseRejection = REASON_PROMISE_REJECTION.equals(severityReasonType);
- boolean anr = event.getImpl().isAnr(event);
+ boolean anr = event.isAnr(event);
if (anr || promiseRejection) {
cacheEvent(event, true);
} else if (immutableConfig.getAttemptDeliveryOnCrash()) {
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.java b/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.java
deleted file mode 100644
index ac498bb174..0000000000
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.java
+++ /dev/null
@@ -1,429 +0,0 @@
-package com.bugsnag.android;
-
-import com.bugsnag.android.internal.ImmutableConfig;
-import com.bugsnag.android.internal.InternalMetrics;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * An Event object represents a Throwable captured by Bugsnag and is available as a parameter on
- * an {@link OnErrorCallback}, where individual properties can be mutated before an error report is
- * sent to Bugsnag's API.
- */
-@SuppressWarnings("ConstantConditions")
-public class Event implements JsonStream.Streamable, MetadataAware, UserAware, FeatureFlagAware {
-
- private final EventInternal impl;
- private final Logger logger;
-
- Event(@Nullable Throwable originalError,
- @NonNull ImmutableConfig config,
- @NonNull SeverityReason severityReason,
- @NonNull Logger logger) {
- this(originalError, config, severityReason, new Metadata(), new FeatureFlags(), logger);
- }
-
- Event(@Nullable Throwable originalError,
- @NonNull ImmutableConfig config,
- @NonNull SeverityReason severityReason,
- @NonNull Metadata metadata,
- @NonNull FeatureFlags featureFlags,
- @NonNull Logger logger) {
- this(new EventInternal(originalError, config, severityReason, metadata, featureFlags),
- logger);
- }
-
- Event(@NonNull EventInternal impl, @NonNull Logger logger) {
- this.impl = impl;
- this.logger = logger;
- }
-
- private void logNull(String property) {
- logger.e("Invalid null value supplied to config." + property + ", ignoring");
- }
-
- /**
- * The Throwable object that caused the event in your application.
- *
- * Manipulating this field does not affect the error information reported to the
- * Bugsnag dashboard. Use {@link Event#getErrors()} to access and amend the representation of
- * the error that will be sent.
- */
- @Nullable
- public Throwable getOriginalError() {
- return impl.getOriginalError();
- }
-
- /**
- * Information extracted from the {@link Throwable} that caused the event can be found in this
- * field. The list contains at least one {@link Error} that represents the thrown object
- * with subsequent elements in the list populated from {@link Throwable#getCause()}.
- *
- * A reference to the actual {@link Throwable} object that caused the event is available
- * through {@link Event#getOriginalError()} ()}.
- */
- @NonNull
- public List getErrors() {
- return impl.getErrors();
- }
-
- /**
- * If thread state is being captured along with the event, this field will contain a
- * list of {@link Thread} objects.
- */
- @NonNull
- public List getThreads() {
- return impl.getThreads();
- }
-
- /**
- * A list of breadcrumbs leading up to the event. These values can be accessed and amended
- * if necessary. See {@link Breadcrumb} for details of the data available.
- */
- @NonNull
- public List getBreadcrumbs() {
- return impl.getBreadcrumbs();
- }
-
- /**
- * A list of feature flags active at the time of the event.
- * See {@link FeatureFlag} for details of the data available.
- */
- @NonNull
- public List getFeatureFlags() {
- return impl.getFeatureFlags().toList();
- }
-
- /**
- * Information set by the notifier about your app can be found in this field. These values
- * can be accessed and amended if necessary.
- */
- @NonNull
- public AppWithState getApp() {
- return impl.getApp();
- }
-
- /**
- * Information set by the notifier about your device can be found in this field. These values
- * can be accessed and amended if necessary.
- */
- @NonNull
- public DeviceWithState getDevice() {
- return impl.getDevice();
- }
-
- /**
- * The API key used for events sent to Bugsnag. Even though the API key is set when Bugsnag
- * is initialized, you may choose to send certain events to a different Bugsnag project.
- */
- public void setApiKey(@NonNull String apiKey) {
- if (apiKey != null) {
- impl.setApiKey(apiKey);
- } else {
- logNull("apiKey");
- }
- }
-
- /**
- * The API key used for events sent to Bugsnag. Even though the API key is set when Bugsnag
- * is initialized, you may choose to send certain events to a different Bugsnag project.
- */
- @NonNull
- public String getApiKey() {
- return impl.getApiKey();
- }
-
- /**
- * The severity of the event. By default, unhandled exceptions will be {@link Severity#ERROR}
- * and handled exceptions sent with {@link Bugsnag#notify} {@link Severity#WARNING}.
- */
- public void setSeverity(@NonNull Severity severity) {
- if (severity != null) {
- impl.setSeverity(severity);
- } else {
- logNull("severity");
- }
- }
-
- /**
- * The severity of the event. By default, unhandled exceptions will be {@link Severity#ERROR}
- * and handled exceptions sent with {@link Bugsnag#notify} {@link Severity#WARNING}.
- */
- @NonNull
- public Severity getSeverity() {
- return impl.getSeverity();
- }
-
- /**
- * Set the grouping hash of the event to override the default grouping on the dashboard.
- * All events with the same grouping hash will be grouped together into one error. This is an
- * advanced usage of the library and mis-using it will cause your events not to group properly
- * in your dashboard.
- *
- * As the name implies, this option accepts a hash of sorts.
- */
- public void setGroupingHash(@Nullable String groupingHash) {
- impl.setGroupingHash(groupingHash);
- }
-
- /**
- * Set the grouping hash of the event to override the default grouping on the dashboard.
- * All events with the same grouping hash will be grouped together into one error. This is an
- * advanced usage of the library and mis-using it will cause your events not to group properly
- * in your dashboard.
- *
- * As the name implies, this option accepts a hash of sorts.
- */
- @Nullable
- public String getGroupingHash() {
- return impl.getGroupingHash();
- }
-
- /**
- * Sets the context of the error. The context is a summary what what was occurring in the
- * application at the time of the crash, if available, such as the visible activity.
- */
- public void setContext(@Nullable String context) {
- impl.setContext(context);
- }
-
- /**
- * Returns the context of the error. The context is a summary what what was occurring in the
- * application at the time of the crash, if available, such as the visible activity.
- */
- @Nullable
- public String getContext() {
- return impl.getContext();
- }
-
- /**
- * Sets the user associated with the event.
- */
- @Override
- public void setUser(@Nullable String id, @Nullable String email, @Nullable String name) {
- impl.setUser(id, email, name);
- }
-
- /**
- * Returns the currently set User information.
- */
- @Override
- @NonNull
- public User getUser() {
- return impl.getUser();
- }
-
- /**
- * Adds a map of multiple metadata key-value pairs to the specified section.
- */
- @Override
- public void addMetadata(@NonNull String section, @NonNull Map value) {
- if (section != null && value != null) {
- impl.addMetadata(section, value);
- } else {
- logNull("addMetadata");
- }
- }
-
- /**
- * Adds the specified key and value in the specified section. The value can be of
- * any primitive type or a collection such as a map, set or array.
- */
- @Override
- public void addMetadata(@NonNull String section, @NonNull String key, @Nullable Object value) {
- if (section != null && key != null) {
- impl.addMetadata(section, key, value);
- } else {
- logNull("addMetadata");
- }
- }
-
- /**
- * Removes all the data from the specified section.
- */
- @Override
- public void clearMetadata(@NonNull String section) {
- if (section != null) {
- impl.clearMetadata(section);
- } else {
- logNull("clearMetadata");
- }
- }
-
- /**
- * Removes data with the specified key from the specified section.
- */
- @Override
- public void clearMetadata(@NonNull String section, @NonNull String key) {
- if (section != null && key != null) {
- impl.clearMetadata(section, key);
- } else {
- logNull("clearMetadata");
- }
- }
-
- /**
- * Returns a map of data in the specified section.
- */
- @Override
- @Nullable
- public Map getMetadata(@NonNull String section) {
- if (section != null) {
- return impl.getMetadata(section);
- } else {
- logNull("getMetadata");
- return null;
- }
- }
-
- /**
- * Returns the value of the specified key in the specified section.
- */
- @Override
- @Nullable
- public Object getMetadata(@NonNull String section, @NonNull String key) {
- if (section != null && key != null) {
- return impl.getMetadata(section, key);
- } else {
- logNull("getMetadata");
- return null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addFeatureFlag(@NonNull String name) {
- if (name != null) {
- impl.addFeatureFlag(name);
- } else {
- logNull("addFeatureFlag");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addFeatureFlag(@NonNull String name, @Nullable String variant) {
- if (name != null) {
- impl.addFeatureFlag(name, variant);
- } else {
- logNull("addFeatureFlag");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addFeatureFlags(@NonNull Iterable featureFlags) {
- if (featureFlags != null) {
- impl.addFeatureFlags(featureFlags);
- } else {
- logNull("addFeatureFlags");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clearFeatureFlag(@NonNull String name) {
- if (name != null) {
- impl.clearFeatureFlag(name);
- } else {
- logNull("clearFeatureFlag");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clearFeatureFlags() {
- impl.clearFeatureFlags();
- }
-
- @Override
- public void toStream(@NonNull JsonStream stream) throws IOException {
- impl.toStream(stream);
- }
-
- /**
- * Whether the event was a crash (i.e. unhandled) or handled error in which the system
- * continued running.
- *
- * Unhandled errors count towards your stability score. If you don't want certain errors
- * to count towards your stability score, you can alter this property through an
- * {@link OnErrorCallback}.
- */
- public boolean isUnhandled() {
- return impl.getUnhandled();
- }
-
- /**
- * Whether the event was a crash (i.e. unhandled) or handled error in which the system
- * continued running.
- *
- * Unhandled errors count towards your stability score. If you don't want certain errors
- * to count towards your stability score, you can alter this property through an
- * {@link OnErrorCallback}.
- */
- public void setUnhandled(boolean unhandled) {
- impl.setUnhandled(unhandled);
- }
-
- protected boolean shouldDiscardClass() {
- return impl.shouldDiscardClass();
- }
-
- protected void updateSeverityInternal(@NonNull Severity severity) {
- impl.updateSeverityInternal(severity);
- }
-
- protected void updateSeverityReason(@NonNull @SeverityReason.SeverityReasonType String reason) {
- impl.updateSeverityReason(reason);
- }
-
- void setApp(@NonNull AppWithState app) {
- impl.setApp(app);
- }
-
- void setDevice(@NonNull DeviceWithState device) {
- impl.setDevice(device);
- }
-
- void setBreadcrumbs(@NonNull List breadcrumbs) {
- impl.setBreadcrumbs(breadcrumbs);
- }
-
- @Nullable
- Session getSession() {
- return impl.session;
- }
-
- void setSession(@Nullable Session session) {
- impl.session = session;
- }
-
- EventInternal getImpl() {
- return impl;
- }
-
- void setRedactedKeys(Collection redactedKeys) {
- impl.setRedactedKeys(redactedKeys);
- }
-
- void setInternalMetrics(InternalMetrics metrics) {
- impl.setInternalMetrics(metrics);
- }
-}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.kt
new file mode 100644
index 0000000000..c85b5c7f68
--- /dev/null
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/Event.kt
@@ -0,0 +1,577 @@
+package com.bugsnag.android
+
+import androidx.annotation.RestrictTo
+import com.bugsnag.android.JsonStream.Streamable
+import com.bugsnag.android.SeverityReason.SeverityReasonType
+import com.bugsnag.android.internal.ImmutableConfig
+import com.bugsnag.android.internal.InternalMetrics
+import com.bugsnag.android.internal.InternalMetricsNoop
+import com.bugsnag.android.internal.JsonHelper
+import com.bugsnag.android.internal.TrimMetrics
+import java.io.IOException
+import java.util.regex.Pattern
+
+/**
+ * An Event object represents a Throwable captured by Bugsnag and is available as a parameter on
+ * an [OnErrorCallback], where individual properties can be mutated before an error report is
+ * sent to Bugsnag's API.
+ */
+class Event : Streamable, MetadataAware, UserAware, FeatureFlagAware {
+
+ internal var severityReason: SeverityReason
+ val logger: Logger
+ internal val metadata: Metadata
+
+ private val jsonStreamer: ObjectJsonStreamer = ObjectJsonStreamer().apply {
+ redactedKeys = redactedKeys.toSet()
+ }
+
+ lateinit var app: AppWithState
+ lateinit var device: DeviceWithState
+
+ var redactedKeys: Collection
+ get() = jsonStreamer.redactedKeys
+ set(value) {
+ jsonStreamer.redactedKeys = value.toSet()
+ metadata.redactedKeys = value.toSet()
+ }
+ var internalMetrics: InternalMetrics = InternalMetricsNoop()
+
+ /**
+ * @return user information associated with this Event
+ */
+ var userImpl: User
+
+ internal constructor(
+ originalError: Throwable?,
+ config: ImmutableConfig,
+ severityReason: SeverityReason,
+ data: Metadata = Metadata(),
+ featureFlags: FeatureFlags = FeatureFlags(),
+ logger: Logger = config.logger
+ ) : this(
+ config.apiKey,
+ logger,
+ mutableListOf(),
+ config.discardClasses.toSet(),
+ when (originalError) {
+ null -> mutableListOf()
+ else -> Error.createError(originalError, config.projectPackages, config.logger)
+ },
+ data.copy(),
+ featureFlags.copy(),
+ originalError,
+ config.projectPackages,
+ severityReason,
+ ThreadState(originalError, severityReason.unhandled, config).threads,
+ User(),
+ config.redactedKeys.toSet()
+ )
+
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+ constructor(
+ originalError: Throwable?,
+ config: ImmutableConfig,
+ severityReason: String,
+ logger: Logger
+ ) : this(
+ originalError,
+ config,
+ SeverityReason.newInstance(severityReason),
+ Metadata(),
+ FeatureFlags(),
+ logger
+ )
+
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+ internal constructor(
+ originalError: Throwable?,
+ config: ImmutableConfig,
+ severityReason: SeverityReason,
+ logger: Logger
+ ) : this(
+ originalError,
+ config,
+ severityReason,
+ Metadata(),
+ FeatureFlags(),
+ logger
+ )
+
+ internal constructor(
+ apiKey: String,
+ logger: Logger,
+ breadcrumbs: MutableList = mutableListOf(),
+ discardClasses: Set = setOf(),
+ errors: MutableList = mutableListOf(),
+ metadata: Metadata = Metadata(),
+ featureFlags: FeatureFlags = FeatureFlags(),
+ originalError: Throwable? = null,
+ projectPackages: Collection = setOf(),
+ severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
+ threads: MutableList = mutableListOf(),
+ user: User = User(),
+ redactionKeys: Set? = null
+ ) {
+ this.logger = logger
+ this.apiKey = apiKey
+ this.breadcrumbs = breadcrumbs
+ this.discardClasses = discardClasses
+ this.errors = errors
+ this.metadata = metadata
+ this._featureFlags = featureFlags
+ this.originalError = originalError
+ this.projectPackages = projectPackages
+ this.severityReason = severityReason
+ this.threads = threads
+ this.userImpl = user
+
+ redactionKeys?.let {
+ this.redactedKeys = it
+ }
+ }
+
+ private fun logNull(property: String) {
+ logger.e("Invalid null value supplied to config.$property, ignoring")
+ }
+
+ /**
+ * The Throwable object that caused the event in your application.
+ *
+ * Manipulating this field does not affect the error information reported to the
+ * Bugsnag dashboard. Use [Event.getErrors] to access and amend the representation of
+ * the error that will be sent.
+ */
+ val originalError: Throwable?
+
+ /**
+ * Information extracted from the [Throwable] that caused the event can be found in this
+ * field. The list contains at least one [Error] that represents the thrown object
+ * with subsequent elements in the list populated from [Throwable.getCause].
+ *
+ * A reference to the actual [Throwable] object that caused the event is available
+ * through [Event.getOriginalError] ()}.
+ */
+ var errors: MutableList
+
+ /**
+ * If thread state is being captured along with the event, this field will contain a
+ * list of [Thread] objects.
+ */
+ var threads: MutableList
+
+ /**
+ * A list of breadcrumbs leading up to the event. These values can be accessed and amended
+ * if necessary. See [Breadcrumb] for details of the data available.
+ */
+ var breadcrumbs: MutableList
+ set(breadcrumbs) {
+ field = breadcrumbs.toMutableList()
+ }
+
+ /**
+ * A list of feature flags active at the time of the event.
+ * See [FeatureFlag] for details of the data available.
+ */
+ val featureFlags: List
+ get() = _featureFlags.toList()
+
+ private val _featureFlags: FeatureFlags
+
+ /**
+ * Information set by the notifier about your app can be found in this field. These values
+ * can be accessed and amended if necessary.
+ */
+ private val discardClasses: Set
+
+ /**
+ * Information set by the notifier about your device can be found in this field. These values
+ * can be accessed and amended if necessary.
+ */
+ internal var projectPackages: Collection
+
+ /**
+ * The API key used for events sent to Bugsnag. Even though the API key is set when Bugsnag
+ * is initialized, you may choose to send certain events to a different Bugsnag project.
+ */
+ /**
+ * The API key used for events sent to Bugsnag. Even though the API key is set when Bugsnag
+ * is initialized, you may choose to send certain events to a different Bugsnag project.
+ */
+ var apiKey: String
+ set(apiKey) =
+ @Suppress("SENSELESS_COMPARISON")
+ if (apiKey != null) {
+ field = apiKey
+ } else {
+ logNull("apiKey")
+ }
+ /**
+ * The severity of the event. By default, unhandled exceptions will be [Severity.ERROR]
+ * and handled exceptions sent with [Bugsnag.notify] [Severity.WARNING].
+ */
+ /**
+ * The severity of the event. By default, unhandled exceptions will be [Severity.ERROR]
+ * and handled exceptions sent with [Bugsnag.notify] [Severity.WARNING].
+ */
+ var severity: Severity
+ get() = severityReason.currentSeverity
+ set(value) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (value != null) {
+ severityReason.currentSeverity = value
+ } else {
+ logNull("severity")
+ }
+ }
+
+ /**
+ * Set the grouping hash of the event to override the default grouping on the dashboard.
+ * All events with the same grouping hash will be grouped together into one error. This is an
+ * advanced usage of the library and mis-using it will cause your events not to group properly
+ * in your dashboard.
+ *
+ * As the name implies, this option accepts a hash of sorts.
+ */
+ /**
+ * Set the grouping hash of the event to override the default grouping on the dashboard.
+ * All events with the same grouping hash will be grouped together into one error. This is an
+ * advanced usage of the library and mis-using it will cause your events not to group properly
+ * in your dashboard.
+ *
+ * As the name implies, this option accepts a hash of sorts.
+ */
+ var groupingHash: String? = null
+ /**
+ * Returns the context of the error. The context is a summary what what was occurring in the
+ * application at the time of the crash, if available, such as the visible activity.
+ */
+ /**
+ * Sets the context of the error. The context is a summary what what was occurring in the
+ * application at the time of the crash, if available, such as the visible activity.
+ */
+ var context: String? = null
+
+ /**
+ * Sets the user associated with the event.
+ */
+ override fun setUser(id: String?, email: String?, name: String?) {
+ userImpl = User(id, email, name)
+ }
+
+ /**
+ * Returns the currently set User information.
+ */
+ override fun getUser(): User {
+ return userImpl
+ }
+
+ /**
+ * Adds a map of multiple metadata key-value pairs to the specified section.
+ */
+ override fun addMetadata(section: String, value: Map) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (section != null && value != null) {
+ metadata.addMetadata(section, value)
+ } else {
+ logNull("addMetadata")
+ }
+ }
+
+ /**
+ * Adds the specified key and value in the specified section. The value can be of
+ * any primitive type or a collection such as a map, set or array.
+ */
+ override fun addMetadata(section: String, key: String, value: Any?) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (section != null && key != null) {
+ metadata.addMetadata(section, key, value)
+ } else {
+ logNull("addMetadata")
+ }
+ }
+
+ /**
+ * Removes all the data from the specified section.
+ */
+ override fun clearMetadata(section: String) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (section != null) {
+ metadata.clearMetadata(section)
+ } else {
+ logNull("clearMetadata")
+ }
+ }
+
+ /**
+ * Removes data with the specified key from the specified section.
+ */
+ override fun clearMetadata(section: String, key: String) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (section != null && key != null) {
+ metadata.clearMetadata(section, key)
+ } else {
+ logNull("clearMetadata")
+ }
+ }
+
+ /**
+ * Returns a map of data in the specified section.
+ */
+ override fun getMetadata(section: String): Map? {
+ @Suppress("SENSELESS_COMPARISON")
+ return if (section != null) {
+ metadata.getMetadata(section)
+ } else {
+ logNull("getMetadata")
+ null
+ }
+ }
+
+ /**
+ * Returns the value of the specified key in the specified section.
+ */
+ override fun getMetadata(section: String, key: String): Any? {
+ @Suppress("SENSELESS_COMPARISON")
+ return if (section != null && key != null) {
+ metadata.getMetadata(section, key)
+ } else {
+ logNull("getMetadata")
+ null
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun addFeatureFlag(name: String) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (name != null) {
+ _featureFlags.addFeatureFlag(name)
+ } else {
+ logNull("addFeatureFlag")
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun addFeatureFlag(name: String, variant: String?) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (name != null) {
+ _featureFlags.addFeatureFlag(name, variant)
+ } else {
+ logNull("addFeatureFlag")
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun addFeatureFlags(featureFlags: Iterable) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (featureFlags != null) {
+ this._featureFlags.addFeatureFlags(featureFlags)
+ } else {
+ logNull("addFeatureFlags")
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun clearFeatureFlag(name: String) {
+ @Suppress("SENSELESS_COMPARISON")
+ if (name != null) {
+ _featureFlags.clearFeatureFlag(name)
+ } else {
+ logNull("clearFeatureFlag")
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun clearFeatureFlags() {
+ _featureFlags.clearFeatureFlags()
+ }
+
+ @Throws(IOException::class)
+ override fun toStream(parentWriter: JsonStream) {
+ val writer = JsonStream(parentWriter, jsonStreamer)
+ // Write error basics
+ writer.beginObject()
+ writer.name("context").value(context)
+ writer.name("metaData").value(metadata)
+
+ writer.name("severity").value(severity)
+ writer.name("severityReason").value(severityReason)
+ writer.name("unhandled").value(severityReason.unhandled)
+
+ // Write exception info
+ writer.name("exceptions")
+ writer.beginArray()
+ errors.forEach { writer.value(it) }
+ writer.endArray()
+
+ // Write project packages
+ writer.name("projectPackages")
+ writer.beginArray()
+ projectPackages.forEach { writer.value(it) }
+ writer.endArray()
+
+ // Write user info
+ writer.name("user").value(userImpl)
+
+ // Write diagnostics
+ writer.name("app").value(app)
+ writer.name("device").value(device)
+ writer.name("breadcrumbs").value(breadcrumbs)
+ writer.name("groupingHash").value(groupingHash)
+ val usage = internalMetrics.toJsonableMap()
+ if (usage.isNotEmpty()) {
+ writer.name("usage")
+ writer.beginObject()
+ usage.forEach { entry ->
+ writer.name(entry.key).value(entry.value)
+ }
+ writer.endObject()
+ }
+
+ writer.name("threads")
+ writer.beginArray()
+ threads.forEach { writer.value(it) }
+ writer.endArray()
+
+ writer.name("featureFlags").value(_featureFlags)
+
+ if (session != null) {
+ val copy = Session.copySession(session)
+ writer.name("session").beginObject()
+ writer.name("id").value(copy.id)
+ writer.name("startedAt").value(copy.startedAt)
+ writer.name("events").beginObject()
+ writer.name("handled").value(copy.handledCount.toLong())
+ writer.name("unhandled").value(copy.unhandledCount.toLong())
+ writer.endObject()
+ writer.endObject()
+ }
+
+ writer.endObject()
+ }
+
+ var isUnhandled: Boolean
+ @JvmName("setUnhandled") set(unhandled) {
+ severityReason.unhandled = unhandled
+ }
+ @JvmName("isUnhandled") get() = severityReason.unhandled
+
+ fun shouldDiscardClass(): Boolean {
+ return when {
+ errors.isEmpty() -> true
+ else -> errors.any { error ->
+ discardClasses.any { pattern ->
+ pattern.matcher(error.errorClass).matches()
+ }
+ }
+ }
+ }
+
+ internal fun trimMetadataStringsTo(maxLength: Int): TrimMetrics {
+ var stringCount = 0
+ var charCount = 0
+
+ var stringAndCharCounts = metadata.trimMetadataStringsTo(maxLength)
+ stringCount += stringAndCharCounts.itemsTrimmed
+ charCount += stringAndCharCounts.dataTrimmed
+ for (breadcrumb in breadcrumbs) {
+ stringAndCharCounts = breadcrumb.impl.trimMetadataStringsTo(maxLength)
+ stringCount += stringAndCharCounts.itemsTrimmed
+ charCount += stringAndCharCounts.dataTrimmed
+ }
+ return TrimMetrics(stringCount, charCount)
+ }
+
+ internal fun trimBreadcrumbsBy(byteCount: Int): TrimMetrics {
+ var removedBreadcrumbCount = 0
+ var removedByteCount = 0
+ while (removedByteCount < byteCount && breadcrumbs.isNotEmpty()) {
+ val breadcrumb = breadcrumbs.removeAt(0)
+ removedByteCount += JsonHelper.serialize(breadcrumb).size
+ removedBreadcrumbCount++
+ }
+ when (removedBreadcrumbCount) {
+ 1 -> breadcrumbs.add(Breadcrumb("Removed to reduce payload size", logger))
+ else -> breadcrumbs.add(
+ Breadcrumb(
+ "Removed, along with ${removedBreadcrumbCount - 1} older breadcrumbs, to reduce payload size",
+ logger
+ )
+ )
+ }
+ return TrimMetrics(removedBreadcrumbCount, removedByteCount)
+ }
+
+ protected fun isAnr(event: Event): Boolean {
+ val errors = event.errors
+ var errorClass: String? = null
+ if (errors.isNotEmpty()) {
+ val error = errors[0]
+ errorClass = error.errorClass
+ }
+ return "ANR" == errorClass
+ }
+
+ fun getUnhandledOverridden(): Boolean = severityReason.unhandledOverridden
+
+ fun getOriginalUnhandled(): Boolean = severityReason.originalUnhandled
+
+ fun getSeverityReasonType(): String = severityReason.severityReasonType
+
+ internal fun getErrorTypesFromStackframes(): Set {
+ val errorTypes = errors.mapNotNull(Error::getType).toSet()
+ val frameOverrideTypes = errors
+ .map { it.stacktrace }
+ .flatMap { it.mapNotNull(Stackframe::type) }
+ return errorTypes.plus(frameOverrideTypes)
+ }
+
+ internal fun normalizeStackframeErrorTypes() {
+ if (getErrorTypesFromStackframes().size == 1) {
+ errors.flatMap { it.stacktrace }.forEach {
+ it.type = null
+ }
+ }
+ }
+
+ internal fun updateSeverityReasonInternal(severityReason: SeverityReason) {
+ this.severityReason = severityReason
+ }
+
+ fun updateSeverityInternal(severity: Severity) {
+ severityReason = SeverityReason(
+ severityReason.severityReasonType,
+ severity,
+ severityReason.unhandled,
+ severityReason.unhandledOverridden,
+ severityReason.attributeValue,
+ severityReason.attributeKey
+ )
+ }
+
+ fun updateSeverityReason(@SeverityReasonType reason: String) {
+ severityReason = SeverityReason(
+ reason,
+ severityReason.currentSeverity,
+ severityReason.unhandled,
+ severityReason.unhandledOverridden,
+ severityReason.attributeValue,
+ severityReason.attributeKey
+ )
+ }
+
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
+ var session: Session? = null
+ @JvmName("setSession") set
+ @JvmName("getSession") get
+}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventFilenameInfo.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventFilenameInfo.kt
index f7cfd5f9af..594372604b 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventFilenameInfo.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventFilenameInfo.kt
@@ -146,7 +146,7 @@ internal data class EventFilenameInfo(
*/
internal fun findErrorTypesForEvent(obj: Any): Set {
return when (obj) {
- is Event -> obj.impl.getErrorTypesFromStackframes()
+ is Event -> obj.getErrorTypesFromStackframes()
else -> setOf(ErrorType.C)
}
}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventInternal.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventInternal.kt
index 4a1881f71d..2e280b336c 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventInternal.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventInternal.kt
@@ -1,321 +1,321 @@
-package com.bugsnag.android
-
-import com.bugsnag.android.internal.ImmutableConfig
-import com.bugsnag.android.internal.InternalMetrics
-import com.bugsnag.android.internal.InternalMetricsNoop
-import com.bugsnag.android.internal.JsonHelper
-import com.bugsnag.android.internal.TrimMetrics
-import java.io.IOException
-import java.util.regex.Pattern
-
-internal class EventInternal : FeatureFlagAware, JsonStream.Streamable, MetadataAware, UserAware {
-
- @JvmOverloads
- internal constructor(
- originalError: Throwable? = null,
- config: ImmutableConfig,
- severityReason: SeverityReason,
- data: Metadata = Metadata(),
- featureFlags: FeatureFlags = FeatureFlags()
- ) : this(
- config.apiKey,
- config.logger,
- mutableListOf(),
- config.discardClasses.toSet(),
- when (originalError) {
- null -> mutableListOf()
- else -> Error.createError(originalError, config.projectPackages, config.logger)
- },
- data.copy(),
- featureFlags.copy(),
- originalError,
- config.projectPackages,
- severityReason,
- ThreadState(originalError, severityReason.unhandled, config).threads,
- User(),
- config.redactedKeys.toSet()
- )
-
- internal constructor(
- apiKey: String,
- logger: Logger,
- breadcrumbs: MutableList = mutableListOf(),
- discardClasses: Set = setOf(),
- errors: MutableList = mutableListOf(),
- metadata: Metadata = Metadata(),
- featureFlags: FeatureFlags = FeatureFlags(),
- originalError: Throwable? = null,
- projectPackages: Collection = setOf(),
- severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
- threads: MutableList = mutableListOf(),
- user: User = User(),
- redactionKeys: Set? = null
- ) {
- this.logger = logger
- this.apiKey = apiKey
- this.breadcrumbs = breadcrumbs
- this.discardClasses = discardClasses
- this.errors = errors
- this.metadata = metadata
- this.featureFlags = featureFlags
- this.originalError = originalError
- this.projectPackages = projectPackages
- this.severityReason = severityReason
- this.threads = threads
- this.userImpl = user
-
- redactionKeys?.let {
- this.redactedKeys = it
- }
- }
-
- val originalError: Throwable?
- internal var severityReason: SeverityReason
-
- val logger: Logger
- val metadata: Metadata
- val featureFlags: FeatureFlags
- private val discardClasses: Set
- internal var projectPackages: Collection
-
- private val jsonStreamer: ObjectJsonStreamer = ObjectJsonStreamer().apply {
- redactedKeys = redactedKeys.toSet()
- }
-
- @JvmField
- internal var session: Session? = null
-
- var severity: Severity
- get() = severityReason.currentSeverity
- set(value) {
- severityReason.currentSeverity = value
- }
-
- var apiKey: String
- lateinit var app: AppWithState
- lateinit var device: DeviceWithState
- var unhandled: Boolean
- get() = severityReason.unhandled
- set(value) {
- severityReason.unhandled = value
- }
-
- var breadcrumbs: MutableList
- var errors: MutableList
- var threads: MutableList
- var groupingHash: String? = null
- var context: String? = null
-
- var redactedKeys: Collection
- get() = jsonStreamer.redactedKeys
- set(value) {
- jsonStreamer.redactedKeys = value.toSet()
- metadata.redactedKeys = value.toSet()
- }
- var internalMetrics: InternalMetrics = InternalMetricsNoop()
-
- /**
- * @return user information associated with this Event
- */
- internal var userImpl: User
-
- fun getUnhandledOverridden(): Boolean = severityReason.unhandledOverridden
-
- fun getOriginalUnhandled(): Boolean = severityReason.originalUnhandled
-
- protected fun shouldDiscardClass(): Boolean {
- return when {
- errors.isEmpty() -> true
- else -> errors.any { error ->
- discardClasses.any { pattern ->
- pattern.matcher(error.errorClass).matches()
- }
- }
- }
- }
-
- protected fun isAnr(event: Event): Boolean {
- val errors = event.errors
- var errorClass: String? = null
- if (errors.isNotEmpty()) {
- val error = errors[0]
- errorClass = error.errorClass
- }
- return "ANR" == errorClass
- }
-
- @Throws(IOException::class)
- override fun toStream(parentWriter: JsonStream) {
- val writer = JsonStream(parentWriter, jsonStreamer)
- // Write error basics
- writer.beginObject()
- writer.name("context").value(context)
- writer.name("metaData").value(metadata)
-
- writer.name("severity").value(severity)
- writer.name("severityReason").value(severityReason)
- writer.name("unhandled").value(severityReason.unhandled)
-
- // Write exception info
- writer.name("exceptions")
- writer.beginArray()
- errors.forEach { writer.value(it) }
- writer.endArray()
-
- // Write project packages
- writer.name("projectPackages")
- writer.beginArray()
- projectPackages.forEach { writer.value(it) }
- writer.endArray()
-
- // Write user info
- writer.name("user").value(userImpl)
-
- // Write diagnostics
- writer.name("app").value(app)
- writer.name("device").value(device)
- writer.name("breadcrumbs").value(breadcrumbs)
- writer.name("groupingHash").value(groupingHash)
- val usage = internalMetrics.toJsonableMap()
- if (usage.isNotEmpty()) {
- writer.name("usage")
- writer.beginObject()
- usage.forEach { entry ->
- writer.name(entry.key).value(entry.value)
- }
- writer.endObject()
- }
-
- writer.name("threads")
- writer.beginArray()
- threads.forEach { writer.value(it) }
- writer.endArray()
-
- writer.name("featureFlags").value(featureFlags)
-
- if (session != null) {
- val copy = Session.copySession(session)
- writer.name("session").beginObject()
- writer.name("id").value(copy.id)
- writer.name("startedAt").value(copy.startedAt)
- writer.name("events").beginObject()
- writer.name("handled").value(copy.handledCount.toLong())
- writer.name("unhandled").value(copy.unhandledCount.toLong())
- writer.endObject()
- writer.endObject()
- }
-
- writer.endObject()
- }
-
- internal fun getErrorTypesFromStackframes(): Set {
- val errorTypes = errors.mapNotNull(Error::getType).toSet()
- val frameOverrideTypes = errors
- .map { it.stacktrace }
- .flatMap { it.mapNotNull(Stackframe::type) }
- return errorTypes.plus(frameOverrideTypes)
- }
-
- internal fun normalizeStackframeErrorTypes() {
- if (getErrorTypesFromStackframes().size == 1) {
- errors.flatMap { it.stacktrace }.forEach {
- it.type = null
- }
- }
- }
-
- internal fun updateSeverityReasonInternal(severityReason: SeverityReason) {
- this.severityReason = severityReason
- }
-
- protected fun updateSeverityInternal(severity: Severity) {
- severityReason = SeverityReason(
- severityReason.severityReasonType,
- severity,
- severityReason.unhandled,
- severityReason.unhandledOverridden,
- severityReason.attributeValue,
- severityReason.attributeKey
- )
- }
-
- protected fun updateSeverityReason(@SeverityReason.SeverityReasonType reason: String) {
- severityReason = SeverityReason(
- reason,
- severityReason.currentSeverity,
- severityReason.unhandled,
- severityReason.unhandledOverridden,
- severityReason.attributeValue,
- severityReason.attributeKey
- )
- }
-
- fun getSeverityReasonType(): String = severityReason.severityReasonType
-
- fun trimMetadataStringsTo(maxLength: Int): TrimMetrics {
- var stringCount = 0
- var charCount = 0
-
- var stringAndCharCounts = metadata.trimMetadataStringsTo(maxLength)
- stringCount += stringAndCharCounts.itemsTrimmed
- charCount += stringAndCharCounts.dataTrimmed
- for (breadcrumb in breadcrumbs) {
- stringAndCharCounts = breadcrumb.impl.trimMetadataStringsTo(maxLength)
- stringCount += stringAndCharCounts.itemsTrimmed
- charCount += stringAndCharCounts.dataTrimmed
- }
- return TrimMetrics(stringCount, charCount)
- }
-
- fun trimBreadcrumbsBy(byteCount: Int): TrimMetrics {
- var removedBreadcrumbCount = 0
- var removedByteCount = 0
- while (removedByteCount < byteCount && breadcrumbs.isNotEmpty()) {
- val breadcrumb = breadcrumbs.removeAt(0)
- removedByteCount += JsonHelper.serialize(breadcrumb).size
- removedBreadcrumbCount++
- }
- when (removedBreadcrumbCount) {
- 1 -> breadcrumbs.add(Breadcrumb("Removed to reduce payload size", logger))
- else -> breadcrumbs.add(
- Breadcrumb(
- "Removed, along with ${removedBreadcrumbCount - 1} older breadcrumbs, to reduce payload size",
- logger
- )
- )
- }
- return TrimMetrics(removedBreadcrumbCount, removedByteCount)
- }
-
- override fun setUser(id: String?, email: String?, name: String?) {
- userImpl = User(id, email, name)
- }
-
- override fun getUser() = userImpl
-
- override fun addMetadata(section: String, value: Map) =
- metadata.addMetadata(section, value)
-
- override fun addMetadata(section: String, key: String, value: Any?) =
- metadata.addMetadata(section, key, value)
-
- override fun clearMetadata(section: String) = metadata.clearMetadata(section)
-
- override fun clearMetadata(section: String, key: String) = metadata.clearMetadata(section, key)
-
- override fun getMetadata(section: String) = metadata.getMetadata(section)
-
- override fun getMetadata(section: String, key: String) = metadata.getMetadata(section, key)
-
- override fun addFeatureFlag(name: String) = featureFlags.addFeatureFlag(name)
-
- override fun addFeatureFlag(name: String, variant: String?) =
- featureFlags.addFeatureFlag(name, variant)
-
- override fun addFeatureFlags(featureFlags: Iterable) =
- this.featureFlags.addFeatureFlags(featureFlags)
-
- override fun clearFeatureFlag(name: String) = featureFlags.clearFeatureFlag(name)
-
- override fun clearFeatureFlags() = featureFlags.clearFeatureFlags()
-}
+// package com.bugsnag.android
+//
+// import com.bugsnag.android.internal.ImmutableConfig
+// import com.bugsnag.android.internal.InternalMetrics
+// import com.bugsnag.android.internal.InternalMetricsNoop
+// import com.bugsnag.android.internal.JsonHelper
+// import com.bugsnag.android.internal.TrimMetrics
+// import java.io.IOException
+// import java.util.regex.Pattern
+//
+// class EventInternal : FeatureFlagAware, JsonStream.Streamable, MetadataAware, UserAware {
+//
+// @JvmOverloads
+// internal constructor(
+// originalError: Throwable? = null,
+// config: ImmutableConfig,
+// severityReason: SeverityReason,
+// data: Metadata = Metadata(),
+// featureFlags: FeatureFlags = FeatureFlags()
+// ) : this(
+// config.apiKey,
+// config.logger,
+// mutableListOf(),
+// config.discardClasses.toSet(),
+// when (originalError) {
+// null -> mutableListOf()
+// else -> Error.createError(originalError, config.projectPackages, config.logger)
+// },
+// data.copy(),
+// featureFlags.copy(),
+// originalError,
+// config.projectPackages,
+// severityReason,
+// ThreadState(originalError, severityReason.unhandled, config).threads,
+// User(),
+// config.redactedKeys.toSet()
+// )
+//
+// internal constructor(
+// apiKey: String,
+// logger: Logger,
+// breadcrumbs: MutableList = mutableListOf(),
+// discardClasses: Set = setOf(),
+// errors: MutableList = mutableListOf(),
+// metadata: Metadata = Metadata(),
+// featureFlags: FeatureFlags = FeatureFlags(),
+// originalError: Throwable? = null,
+// projectPackages: Collection = setOf(),
+// severityReason: SeverityReason = SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
+// threads: MutableList = mutableListOf(),
+// user: User = User(),
+// redactionKeys: Set? = null
+// ) {
+// this.logger = logger
+// this.apiKey = apiKey
+// this.breadcrumbs = breadcrumbs
+// this.discardClasses = discardClasses
+// this.errors = errors
+// this.metadata = metadata
+// this.featureFlags = featureFlags
+// this.originalError = originalError
+// this.projectPackages = projectPackages
+// this.severityReason = severityReason
+// this.threads = threads
+// this.userImpl = user
+//
+// redactionKeys?.let {
+// this.redactedKeys = it
+// }
+// }
+//
+// val originalError: Throwable?
+// internal var severityReason: SeverityReason
+//
+// val logger: Logger
+// internal val metadata: Metadata
+// internal val featureFlags: FeatureFlags
+// private val discardClasses: Set
+// internal var projectPackages: Collection
+//
+// private val jsonStreamer: ObjectJsonStreamer = ObjectJsonStreamer().apply {
+// redactedKeys = redactedKeys.toSet()
+// }
+//
+// @JvmField
+// internal var session: Session? = null
+//
+// var severity: Severity
+// get() = severityReason.currentSeverity
+// set(value) {
+// severityReason.currentSeverity = value
+// }
+//
+// var apiKey: String
+// lateinit var app: AppWithState
+// lateinit var device: DeviceWithState
+// var unhandled: Boolean
+// get() = severityReason.unhandled
+// set(value) {
+// severityReason.unhandled = value
+// }
+//
+// var breadcrumbs: MutableList
+// var errors: MutableList
+// var threads: MutableList
+// var groupingHash: String? = null
+// var context: String? = null
+//
+// var redactedKeys: Collection
+// get() = jsonStreamer.redactedKeys
+// set(value) {
+// jsonStreamer.redactedKeys = value.toSet()
+// metadata.redactedKeys = value.toSet()
+// }
+// var internalMetrics: InternalMetrics = InternalMetricsNoop()
+//
+// /**
+// * @return user information associated with this Event
+// */
+// internal var userImpl: User
+//
+// fun getUnhandledOverridden(): Boolean = severityReason.unhandledOverridden
+//
+// fun getOriginalUnhandled(): Boolean = severityReason.originalUnhandled
+//
+// public fun shouldDiscardClass(): Boolean {
+// return when {
+// errors.isEmpty() -> true
+// else -> errors.any { error ->
+// discardClasses.any { pattern ->
+// pattern.matcher(error.errorClass).matches()
+// }
+// }
+// }
+// }
+//
+// protected fun isAnr(event: Event): Boolean {
+// val errors = event.errors
+// var errorClass: String? = null
+// if (errors.isNotEmpty()) {
+// val error = errors[0]
+// errorClass = error.errorClass
+// }
+// return "ANR" == errorClass
+// }
+//
+// @Throws(IOException::class)
+// override fun toStream(parentWriter: JsonStream) {
+// val writer = JsonStream(parentWriter, jsonStreamer)
+// // Write error basics
+// writer.beginObject()
+// writer.name("context").value(context)
+// writer.name("metaData").value(metadata)
+//
+// writer.name("severity").value(severity)
+// writer.name("severityReason").value(severityReason)
+// writer.name("unhandled").value(severityReason.unhandled)
+//
+// // Write exception info
+// writer.name("exceptions")
+// writer.beginArray()
+// errors.forEach { writer.value(it) }
+// writer.endArray()
+//
+// // Write project packages
+// writer.name("projectPackages")
+// writer.beginArray()
+// projectPackages.forEach { writer.value(it) }
+// writer.endArray()
+//
+// // Write user info
+// writer.name("user").value(userImpl)
+//
+// // Write diagnostics
+// writer.name("app").value(app)
+// writer.name("device").value(device)
+// writer.name("breadcrumbs").value(breadcrumbs)
+// writer.name("groupingHash").value(groupingHash)
+// val usage = internalMetrics.toJsonableMap()
+// if (usage.isNotEmpty()) {
+// writer.name("usage")
+// writer.beginObject()
+// usage.forEach { entry ->
+// writer.name(entry.key).value(entry.value)
+// }
+// writer.endObject()
+// }
+//
+// writer.name("threads")
+// writer.beginArray()
+// threads.forEach { writer.value(it) }
+// writer.endArray()
+//
+// writer.name("featureFlags").value(featureFlags)
+//
+// if (session != null) {
+// val copy = Session.copySession(session)
+// writer.name("session").beginObject()
+// writer.name("id").value(copy.id)
+// writer.name("startedAt").value(copy.startedAt)
+// writer.name("events").beginObject()
+// writer.name("handled").value(copy.handledCount.toLong())
+// writer.name("unhandled").value(copy.unhandledCount.toLong())
+// writer.endObject()
+// writer.endObject()
+// }
+//
+// writer.endObject()
+// }
+//
+// internal fun getErrorTypesFromStackframes(): Set {
+// val errorTypes = errors.mapNotNull(Error::getType).toSet()
+// val frameOverrideTypes = errors
+// .map { it.stacktrace }
+// .flatMap { it.mapNotNull(Stackframe::type) }
+// return errorTypes.plus(frameOverrideTypes)
+// }
+//
+// internal fun normalizeStackframeErrorTypes() {
+// if (getErrorTypesFromStackframes().size == 1) {
+// errors.flatMap { it.stacktrace }.forEach {
+// it.type = null
+// }
+// }
+// }
+//
+// internal fun updateSeverityReasonInternal(severityReason: SeverityReason) {
+// this.severityReason = severityReason
+// }
+//
+// public fun updateSeverityInternal(severity: Severity) {
+// severityReason = SeverityReason(
+// severityReason.severityReasonType,
+// severity,
+// severityReason.unhandled,
+// severityReason.unhandledOverridden,
+// severityReason.attributeValue,
+// severityReason.attributeKey
+// )
+// }
+//
+// public fun updateSeverityReason(@SeverityReason.SeverityReasonType reason: String) {
+// severityReason = SeverityReason(
+// reason,
+// severityReason.currentSeverity,
+// severityReason.unhandled,
+// severityReason.unhandledOverridden,
+// severityReason.attributeValue,
+// severityReason.attributeKey
+// )
+// }
+//
+// fun getSeverityReasonType(): String = severityReason.severityReasonType
+//
+// internal fun trimMetadataStringsTo(maxLength: Int): TrimMetrics {
+// var stringCount = 0
+// var charCount = 0
+//
+// var stringAndCharCounts = metadata.trimMetadataStringsTo(maxLength)
+// stringCount += stringAndCharCounts.itemsTrimmed
+// charCount += stringAndCharCounts.dataTrimmed
+// for (breadcrumb in breadcrumbs) {
+// stringAndCharCounts = breadcrumb.impl.trimMetadataStringsTo(maxLength)
+// stringCount += stringAndCharCounts.itemsTrimmed
+// charCount += stringAndCharCounts.dataTrimmed
+// }
+// return TrimMetrics(stringCount, charCount)
+// }
+//
+// internal fun trimBreadcrumbsBy(byteCount: Int): TrimMetrics {
+// var removedBreadcrumbCount = 0
+// var removedByteCount = 0
+// while (removedByteCount < byteCount && breadcrumbs.isNotEmpty()) {
+// val breadcrumb = breadcrumbs.removeAt(0)
+// removedByteCount += JsonHelper.serialize(breadcrumb).size
+// removedBreadcrumbCount++
+// }
+// when (removedBreadcrumbCount) {
+// 1 -> breadcrumbs.add(Breadcrumb("Removed to reduce payload size", logger))
+// else -> breadcrumbs.add(
+// Breadcrumb(
+// "Removed, along with ${removedBreadcrumbCount - 1} older breadcrumbs, to reduce payload size",
+// logger
+// )
+// )
+// }
+// return TrimMetrics(removedBreadcrumbCount, removedByteCount)
+// }
+//
+// override fun setUser(id: String?, email: String?, name: String?) {
+// userImpl = User(id, email, name)
+// }
+//
+// override fun getUser() = userImpl
+//
+// override fun addMetadata(section: String, value: Map) =
+// metadata.addMetadata(section, value)
+//
+// override fun addMetadata(section: String, key: String, value: Any?) =
+// metadata.addMetadata(section, key, value)
+//
+// override fun clearMetadata(section: String) = metadata.clearMetadata(section)
+//
+// override fun clearMetadata(section: String, key: String) = metadata.clearMetadata(section, key)
+//
+// override fun getMetadata(section: String) = metadata.getMetadata(section)
+//
+// override fun getMetadata(section: String, key: String) = metadata.getMetadata(section, key)
+//
+// override fun addFeatureFlag(name: String) = featureFlags.addFeatureFlag(name)
+//
+// override fun addFeatureFlag(name: String, variant: String?) =
+// featureFlags.addFeatureFlag(name, variant)
+//
+// override fun addFeatureFlags(featureFlags: Iterable) =
+// this.featureFlags.addFeatureFlags(featureFlags)
+//
+// override fun clearFeatureFlag(name: String) = featureFlags.clearFeatureFlag(name)
+//
+// override fun clearFeatureFlags() = featureFlags.clearFeatureFlags()
+// }
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventPayload.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventPayload.kt
index 51f213016d..5b84fda8c1 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/EventPayload.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/EventPayload.kt
@@ -28,7 +28,7 @@ class EventPayload @JvmOverloads internal constructor(
internal fun getErrorTypes(): Set {
val event = this.event
return when {
- event != null -> event.impl.getErrorTypesFromStackframes()
+ event != null -> event.getErrorTypesFromStackframes()
eventFile != null -> EventFilenameInfo.fromFile(eventFile, config).errorTypes
else -> emptySet()
}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/MarshalledEventSource.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/MarshalledEventSource.kt
index cd5fbf69e0..534f337ccd 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/MarshalledEventSource.kt
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/MarshalledEventSource.kt
@@ -34,9 +34,6 @@ internal class MarshalledEventSource(
private fun unmarshall(): Event {
val eventMapper = BugsnagEventMapper(logger)
val jsonMap = JsonHelper.deserialize(eventFile)
- return Event(
- eventMapper.convertToEventImpl(jsonMap, apiKey),
- logger
- )
+ return eventMapper.convertToEventImpl(jsonMap, apiKey)
}
}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/NativeInterface.java b/bugsnag-android-core/src/main/java/com/bugsnag/android/NativeInterface.java
index 6f622fdf27..dbabe4d213 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/NativeInterface.java
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/NativeInterface.java
@@ -54,12 +54,11 @@ private static Event createEmptyEvent() {
Client client = getClient();
return new Event(
- new EventInternal(
- (Throwable) null,
- client.getConfig(),
- SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
- client.getMetadataState().getMetadata().copy()
- ),
+ (Throwable) null,
+ client.getConfig(),
+ SeverityReason.newInstance(SeverityReason.REASON_HANDLED_EXCEPTION),
+ client.getMetadataState().getMetadata().copy(),
+ client.getFeatureFlagState().getFeatureFlags(),
client.getLogger()
);
}
diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/SeverityReason.java b/bugsnag-android-core/src/main/java/com/bugsnag/android/SeverityReason.java
index e759bd6d59..054d12d873 100644
--- a/bugsnag-android-core/src/main/java/com/bugsnag/android/SeverityReason.java
+++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/SeverityReason.java
@@ -5,6 +5,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
import androidx.annotation.StringDef;
import java.io.IOException;
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventApiTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventApiTest.kt
index 91e4ba9e4a..a9b1318eb8 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventApiTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventApiTest.kt
@@ -30,39 +30,39 @@ internal class EventApiTest {
@Test
fun getUser() {
- assertEquals(event.impl.userImpl, event.getUser())
+ assertEquals(event.userImpl, event.getUser())
}
@Test
fun setUser() {
event.setUser("99", "boo@example.com", "Boo")
- assertEquals(User("99", "boo@example.com", "Boo"), event.impl.userImpl)
+ assertEquals(User("99", "boo@example.com", "Boo"), event.userImpl)
}
@Test
fun addMetadataTopLevel() {
event.addMetadata("foo", mapOf(Pair("wham", "bar")))
- assertEquals(mapOf(Pair("wham", "bar")), event.impl.metadata.getMetadata("foo"))
+ assertEquals(mapOf(Pair("wham", "bar")), event.metadata.getMetadata("foo"))
}
@Test
fun addMetadata() {
event.addMetadata("foo", "wham", "bar")
- assertEquals("bar", event.impl.metadata.getMetadata("foo", "wham"))
+ assertEquals("bar", event.metadata.getMetadata("foo", "wham"))
}
@Test
fun clearMetadataTopLevel() {
event.addMetadata("foo", mapOf(Pair("wham", "bar")))
event.clearMetadata("foo")
- assertNull(event.impl.metadata.getMetadata("foo"))
+ assertNull(event.metadata.getMetadata("foo"))
}
@Test
fun clearMetadata() {
event.addMetadata("foo", "wham", "bar")
event.clearMetadata("foo", "wham")
- assertNull(event.impl.metadata.getMetadata("foo", "wham"))
+ assertNull(event.metadata.getMetadata("foo", "wham"))
}
@Test
@@ -70,7 +70,7 @@ internal class EventApiTest {
event.addFeatureFlag("demo_mode")
assertEquals(
listOf(FeatureFlag("demo_mode")),
- event.impl.featureFlags.toList()
+ event.featureFlags.toList()
)
}
@@ -79,7 +79,7 @@ internal class EventApiTest {
event.addFeatureFlag("sample_group", "a")
assertEquals(
listOf(FeatureFlag("sample_group", "a")),
- event.impl.featureFlags.toList()
+ event.featureFlags.toList()
)
}
@@ -90,7 +90,7 @@ internal class EventApiTest {
event.clearFeatureFlag("demo_group")
assertEquals(
listOf(FeatureFlag("sample_group", "a")),
- event.impl.featureFlags.toList()
+ event.featureFlags.toList()
)
}
@@ -99,6 +99,6 @@ internal class EventApiTest {
event.addFeatureFlag("demo_group")
event.addFeatureFlag("sample_group", "a")
event.clearFeatureFlags()
- assertEquals(emptyList(), event.impl.featureFlags.toList())
+ assertEquals(emptyList(), event.featureFlags.toList())
}
}
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventErrorTypeTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventErrorTypeTest.kt
index a743f279be..9831aa95bd 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventErrorTypeTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventErrorTypeTest.kt
@@ -49,7 +49,7 @@ class EventErrorTypeTest {
assertEquals(setOf(ANDROID), payload.getErrorTypes())
// confirm single type is stripped from individual stackframes
- event.impl.normalizeStackframeErrorTypes()
+ event.normalizeStackframeErrorTypes()
assertEquals(ANDROID, error.type)
assertEquals(setOf(ANDROID), payload.getErrorTypes())
error.stacktrace.forEach { assertNull(it.type) }
@@ -80,7 +80,7 @@ class EventErrorTypeTest {
assertEquals(setOf(ANDROID, C), payload.getErrorTypes())
// confirm single type is stripped from individual stackframes
- event.impl.normalizeStackframeErrorTypes()
+ event.normalizeStackframeErrorTypes()
assertEquals(ANDROID, error.type)
assertEquals(setOf(ANDROID, C), payload.getErrorTypes())
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventFeatureFlagsCloneTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventFeatureFlagsCloneTest.kt
index 1092c45db7..a7834b2d90 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventFeatureFlagsCloneTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventFeatureFlagsCloneTest.kt
@@ -27,7 +27,7 @@ class EventFeatureFlagsCloneTest {
event.addFeatureFlag("demo_mode")
// featureFlags objects should be deep copied
- assertNotSame(featureFlags, event.impl.featureFlags)
+ assertNotSame(featureFlags, event.featureFlags)
// validate origin featureFlags
val origExpected = listOf(FeatureFlag("sample_group", "123"))
@@ -38,6 +38,6 @@ class EventFeatureFlagsCloneTest {
FeatureFlag("sample_group", "123"),
FeatureFlag("demo_mode")
)
- assertEquals(eventExpected, event.impl.featureFlags.toList())
+ assertEquals(eventExpected, event.featureFlags.toList())
}
}
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventMetadataCloneTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventMetadataCloneTest.kt
index 2dd94a0163..9520541e73 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventMetadataCloneTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventMetadataCloneTest.kt
@@ -27,7 +27,7 @@ class EventMetadataCloneTest {
event.addMetadata("test_section", "second", "another value")
// metadata object should be deep copied
- assertNotSame(data, event.impl.metadata)
+ assertNotSame(data, event.metadata)
// validate event metadata
val origExpected = mapOf(Pair("foo", "bar"))
@@ -35,6 +35,6 @@ class EventMetadataCloneTest {
// validate event metadata
val eventExpected = mapOf(Pair("foo", "bar"), Pair("second", "another value"))
- assertEquals(eventExpected, event.impl.metadata.getMetadata("test_section"))
+ assertEquals(eventExpected, event.metadata.getMetadata("test_section"))
}
}
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventRedactionTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventRedactionTest.kt
index 24c41ccf75..b2f9e253b3 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventRedactionTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventRedactionTest.kt
@@ -41,9 +41,9 @@ internal class EventRedactionTest {
event.addMetadata("app", "password", "foo")
event.addMetadata("device", "password", "bar")
- event.impl.metadata.addMetadata("baz", "password", "hunter2")
+ event.metadata.addMetadata("baz", "password", "hunter2")
val metadata = mutableMapOf(Pair("changeme", "whoops"))
- event.breadcrumbs = listOf(Breadcrumb("Whoops", BreadcrumbType.LOG, metadata, Date(0), NoopLogger))
+ event.breadcrumbs = mutableListOf(Breadcrumb("Whoops", BreadcrumbType.LOG, metadata, Date(0), NoopLogger))
event.threads.clear()
event.device.cpuAbi = emptyArray()
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventSerializationTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventSerializationTest.kt
index f930fe313c..aaf4c5f146 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventSerializationTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventSerializationTest.kt
@@ -35,7 +35,8 @@ internal class EventSerializationTest {
createEvent {
val user = User("123", "foo@example.com", "Joe")
val apiKey = "BUGSNAG_API_KEY"
- it.session = Session("123", Date(0), user, false, Notifier(), NoopLogger, apiKey)
+ it.session =
+ Session("123", Date(0), user, false, Notifier(), NoopLogger, apiKey)
},
// threads included
@@ -69,7 +70,7 @@ internal class EventSerializationTest {
Date(0),
NoopLogger
)
- it.breadcrumbs = listOf(crumb)
+ it.breadcrumbs = mutableListOf(crumb)
val stacktrace = Stacktrace(arrayOf(), emptySet(), NoopLogger)
val err =
@@ -113,10 +114,7 @@ internal class EventSerializationTest {
@Test
fun testJsonDeserializion() {
verifyJsonParser(testCase.first, testCase.second) {
- Event(
- eventMapper.convertToEventImpl(it, "5d1ec5bd39a74caa1267142706a7fb21"),
- NoopLogger
- )
+ eventMapper.convertToEventImpl(it, "5d1ec5bd39a74caa1267142706a7fb21")
}
}
}
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventTest.java b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventTest.java
index c7dca05b62..aaa519baae 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/EventTest.java
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/EventTest.java
@@ -166,22 +166,22 @@ public void testGetSetErrors() {
public void testIsAnr() {
RuntimeException exc = new RuntimeException("Something went wrong");
Event event = new Event(exc, config, severityReason, NoopLogger.INSTANCE);
- assertFalse(event.getImpl().isAnr(event));
+ assertFalse(event.isAnr(event));
// simulate ANR
event.getErrors().get(0).setErrorClass("ANR");
- assertTrue(event.getImpl().isAnr(event));
+ assertTrue(event.isAnr(event));
// clear all errors
event.getErrors().clear();
- assertFalse(event.getImpl().isAnr(event));
+ assertFalse(event.isAnr(event));
}
@Test
public void testSeverityReasonType() {
RuntimeException exc = new RuntimeException("Something went wrong");
Event event = new Event(exc, config, severityReason, NoopLogger.INSTANCE);
- String severityReasonType = event.getImpl().getSeverityReasonType();
+ String severityReasonType = event.getSeverityReasonType();
assertEquals(SeverityReason.REASON_HANDLED_EXCEPTION, severityReasonType);
}
@@ -190,13 +190,13 @@ public void testSeverityReasonInternalOverload() {
RuntimeException exc = new RuntimeException("Something went wrong");
Event event = new Event(exc, config, severityReason, NoopLogger.INSTANCE);
- String severityReasonType = event.getImpl().getSeverityReasonType();
+ String severityReasonType = event.getSeverityReasonType();
assertEquals(SeverityReason.REASON_HANDLED_EXCEPTION, severityReasonType);
assertEquals(Severity.WARNING, event.getSeverity());
event.updateSeverityInternal(Severity.INFO);
event.updateSeverityReason(SeverityReason.REASON_STRICT_MODE);
- severityReasonType = event.getImpl().getSeverityReasonType();
+ severityReasonType = event.getSeverityReasonType();
assertEquals(SeverityReason.REASON_STRICT_MODE, severityReasonType);
assertEquals(Severity.INFO, event.getSeverity());
}
diff --git a/bugsnag-android-core/src/test/java/com/bugsnag/android/NativeInterfaceApiTest.kt b/bugsnag-android-core/src/test/java/com/bugsnag/android/NativeInterfaceApiTest.kt
index dce80a6b79..befae79cdb 100644
--- a/bugsnag-android-core/src/test/java/com/bugsnag/android/NativeInterfaceApiTest.kt
+++ b/bugsnag-android-core/src/test/java/com/bugsnag/android/NativeInterfaceApiTest.kt
@@ -76,6 +76,7 @@ internal class NativeInterfaceApiTest {
`when`(client.getDeviceDataCollector()).thenReturn(deviceDataCollector)
`when`(client.getUser()).thenReturn(User("123", "tod@example.com", "Tod"))
`when`(client.getMetadataState()).thenReturn(MetadataState())
+ `when`(client.getFeatureFlagState()).thenReturn(FeatureFlagState())
}
@Test
diff --git a/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TombstoneEventEnhancerTest.kt b/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TombstoneEventEnhancerTest.kt
index b2507c3b88..95bf46bb41 100644
--- a/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TombstoneEventEnhancerTest.kt
+++ b/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TombstoneEventEnhancerTest.kt
@@ -26,7 +26,7 @@ internal class TombstoneEventEnhancerTest {
val event = Event(
RuntimeException("error"),
mock(ImmutableConfig::class.java),
- SeverityReason.newInstance(SeverityReason.REASON_SIGNAL),
+ SeverityReason.REASON_SIGNAL,
logger
)
val oldThread = BugsnagThread(
diff --git a/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TraceEventEnhancerTest.kt b/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TraceEventEnhancerTest.kt
index 176d093775..4fbda69380 100644
--- a/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TraceEventEnhancerTest.kt
+++ b/bugsnag-plugin-android-exitinfo/src/test/java/com/bugsnag/android/TraceEventEnhancerTest.kt
@@ -17,7 +17,7 @@ class TraceEventEnhancerTest {
val event = Event(
RuntimeException("error"),
mock(ImmutableConfig::class.java),
- SeverityReason.newInstance(SeverityReason.REASON_ANR),
+ SeverityReason.REASON_ANR,
mockLogger
)
diff --git a/bugsnag-plugin-react-native/src/test/java/com/bugsnag/android/TestHooks.java b/bugsnag-plugin-react-native/src/test/java/com/bugsnag/android/TestHooks.java
index e9b628b612..e29d697aa1 100644
--- a/bugsnag-plugin-react-native/src/test/java/com/bugsnag/android/TestHooks.java
+++ b/bugsnag-plugin-react-native/src/test/java/com/bugsnag/android/TestHooks.java
@@ -2,7 +2,7 @@
class TestHooks {
static boolean getUnhandledOverridden(Event event) {
- return event.getImpl().getUnhandledOverridden();
+ return event.getUnhandledOverridden();
}
static MetadataState generateMetadataState() {