Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Sentry with BugSnag for error reporting #313

Merged
merged 15 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/android_prod_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ jobs:
TERM: dumb
ORG_GRADLE_PROJECT_READER_KEYSTORE_PASSWORD: ${{ secrets.READER_KEYSTORE_PASSWORD }}
ORG_GRADLE_PROJECT_READER_KEY_PASSWORD: ${{ secrets.READER_KEY_PASSWORD }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
steps:
- name: Configure Tramline
id: tramline
Expand Down
16 changes: 7 additions & 9 deletions .github/workflows/ios_prod_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: macos-14
env:
TERM: dumb
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }}
steps:
- name: Configure Tramline
id: tramline
Expand Down Expand Up @@ -78,6 +78,7 @@ jobs:
-destination generic/platform=iOS \
DEVELOPMENT_TEAM=6XCS8KZXDA \
PROVISIONING_PROFILE=${{ secrets.PROVISION_PROFILE_ID }} \
BUGSNAG_API_KEY=${BUGSNAG_API_KEY} \
clean archive
CODE_SIGN_IDENTITY="iPhone Distribution: Sasi Kanth (6XCS8KZXDA)"

Expand All @@ -89,15 +90,12 @@ jobs:
echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH
xcodebuild -exportArchive -archivePath $RUNNER_TEMP/twine.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build

- name: Upload debug symbols to Sentry
- name: Upload debug symbols to Bugsnag
run: |
curl -sL https://sentry.io/get-cli/ | SENTRY_CLI_VERSION=2.21.2 bash;

sentry-cli debug-files upload --auth-token ${{ secrets.SENTRY_AUTH_TOKEN }} \
--include-sources \
--org ${{ secrets.SENTRY_ORG }} \
--project ${{ secrets.SENTRY_PROJECT }} \
$RUNNER_TEMP/twine.xcarchive/dSYMs
cd $RUNNER_TEMP/twine.xcarchive/dSYMs/;
curl --http1.1 https://upload.bugsnag.com/ \
-F apiKey=${BUGSNAG_API_KEY} \
-F [email protected]/Contents/Resources/DWARF/Twine \

- name: Clean up keychain and provisioning profile
if: ${{ always() }}
Expand Down
8 changes: 4 additions & 4 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.compose)
alias(libs.plugins.ksp)
alias(libs.plugins.sentry.android)
}

sentry { tracingInstrumentation { enabled = false } }

kotlin {
jvmToolchain(20)

Expand All @@ -41,6 +38,9 @@ android {
minSdk = libs.versions.android.sdk.min.get().toInt()
targetSdk = libs.versions.android.sdk.target.get().toInt()

val keyBugsnagAPIKey = "BUGSNAG_API_KEY"
manifestPlaceholders[keyBugsnagAPIKey] = System.getenv(keyBugsnagAPIKey).orEmpty()

versionCode =
if (project.properties["VERSION_CODE"] != null) {
(project.properties["VERSION_CODE"] as String).toInt()
Expand Down Expand Up @@ -95,7 +95,7 @@ dependencies {
implementation(libs.kotlininject.runtime)
ksp(libs.kotlininject.compiler)
implementation(libs.androidx.work)
implementation(libs.sentry)
coreLibraryDesugaring(libs.desugarJdk)
implementation(libs.kotlinx.datetime)
implementation(libs.bugsnag)
}
4 changes: 4 additions & 0 deletions androidApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
tools:targetApi="tiramisu">

<meta-data android:name="com.bugsnag.android.API_KEY"
android:value="${BUGSNAG_API_KEY}"/>

<activity
android:name="dev.sasikanth.rss.reader.MainActivity"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequest
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkerParameters
import co.touchlab.crashkios.bugsnag.BugsnagKotlin
import com.bugsnag.android.Bugsnag
import dev.sasikanth.rss.reader.refresh.LastUpdatedAt
import dev.sasikanth.rss.reader.repository.RssRepository
import io.sentry.kotlin.multiplatform.Sentry
import io.sentry.kotlin.multiplatform.SentryLevel
import io.sentry.kotlin.multiplatform.protocol.Breadcrumb
import java.lang.Exception
import java.time.Duration
import kotlinx.coroutines.CancellationException
Expand Down Expand Up @@ -64,9 +63,8 @@ class FeedsRefreshWorker(
} catch (e: CancellationException) {
Result.failure()
} catch (e: Exception) {
Sentry.captureException(e) {
it.addBreadcrumb(Breadcrumb(level = SentryLevel.INFO, category = "Background"))
}
Bugsnag.leaveBreadcrumb("Background Worker")
BugsnagKotlin.sendFatalException(e)
Result.failure()
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequest
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkerParameters
import co.touchlab.crashkios.bugsnag.BugsnagKotlin
import com.bugsnag.android.Bugsnag
import dev.sasikanth.rss.reader.repository.RssRepository
import dev.sasikanth.rss.reader.repository.SettingsRepository
import dev.sasikanth.rss.reader.utils.calculateInstantBeforePeriod
import io.sentry.Sentry
import java.time.Duration
import kotlin.coroutines.cancellation.CancellationException

Expand Down Expand Up @@ -67,7 +68,8 @@ class PostsCleanUpWorker(
} catch (e: CancellationException) {
// no-op
} catch (e: Exception) {
Sentry.captureException(e)
Bugsnag.leaveBreadcrumb("Background Worker")
BugsnagKotlin.sendFatalException(e)
}

return Result.failure()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import androidx.work.ListenableWorker
import androidx.work.WorkManager
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters
import co.touchlab.crashkios.bugsnag.enableBugsnag
import com.bugsnag.android.Bugsnag
import dev.sasikanth.rss.reader.di.ApplicationComponent
import dev.sasikanth.rss.reader.di.create

Expand Down Expand Up @@ -79,6 +81,12 @@ class ReaderApplication : Application(), Configuration.Provider {

override fun onCreate() {
super.onCreate()

if (!BuildConfig.DEBUG) {
Bugsnag.start(this)
enableBugsnag()
}

enqueuePeriodicFeedsRefresh()
enqueuePeriodicPostsCleanUp()

Expand Down
3 changes: 1 addition & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ plugins {
alias(libs.plugins.android.library).apply(false)
alias(libs.plugins.compose).apply(false)
alias(libs.plugins.spotless).apply(false)
alias(libs.plugins.buildKonfig).apply(false)
alias(libs.plugins.sentry.android).apply(false)
alias(libs.plugins.kotlin.parcelize).apply(false)
alias(libs.plugins.kotlin.serialization).apply(false)
alias(libs.plugins.bugsnag).apply(false)
}

allprojects {
Expand Down
1 change: 0 additions & 1 deletion core/network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ kotlin {
implementation(libs.ksoup)
// TODO: Extract logging abstraction into separate module
implementation(libs.napier)
implementation(libs.sentry)
implementation(libs.ktxml)
}
commonTest.dependencies { implementation(libs.kotlin.test) }
Expand Down
3 changes: 0 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@ org.jetbrains.compose.experimental.uikit.enabled=true
android.useAndroidX=true
android.nonTransitiveRClass=true
android.nonFinalResIds=false
#Sentry
# do_not_change_here
sentry.dsn=
12 changes: 6 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ kotlininject = "0.6.3"
ksp = "1.9.22-1.0.17"
material_color_utilities = "1.0.0-alpha01"
ksoup = "0.1.2"
sentry = "0.3.0"
sentry_android = "4.3.0"
buildKonfig = "0.15.1"
sqliteAndroid = "3.45.0"
windowSizeClass = "0.3.2"
desugarJdk = "2.0.4"
Expand All @@ -48,6 +45,9 @@ ktxml = "0.2.3"
uri = "0.0.16"
webview = "1.8.8"
uuid = "0.8.2"
bugsnag-plugin = "8.1.0"
bugsnag = "6.2.0"
crashkios-bugsnag = "0.8.6"

[libraries]
compose_runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" }
Expand Down Expand Up @@ -96,7 +96,6 @@ kotlininject-compiler = { module = 'me.tatarka.inject:kotlin-inject-compiler-ksp
kotlininject-runtime = { module = 'me.tatarka.inject:kotlin-inject-runtime', version.ref = 'kotlininject' }
material_color_utilities = { module = "dev.sasikanth:material-color-utilities", version.ref = "material_color_utilities" }
ksoup = { module = "com.fleeksoft.ksoup:ksoup", version.ref = "ksoup" }
sentry = { module = "io.sentry:sentry-kotlin-multiplatform", version.ref = "sentry" }
sqliteAndroid = { module = "com.github.requery:sqlite-android", version.ref = "sqliteAndroid" }
windowSizeClass = { module = "dev.chrisbanes.material3:material3-window-size-class-multiplatform", version.ref = "windowSizeClass" }
desugarJdk = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugarJdk" }
Expand All @@ -113,6 +112,8 @@ ktxml = { module = "org.kobjects.ktxml:core", version.ref = "ktxml" }
uri = { module = "com.eygraber:uri-kmp", version.ref = "uri" }
webview = { module = "io.github.kevinnzou:compose-webview-multiplatform", version.ref = "webview" }
uuid = { module = "com.benasher44:uuid", version.ref = "uuid" }
bugsnag = { module = "com.bugsnag:bugsnag-android", version.ref = "bugsnag" }
crashkios-bugsnag = { module = "co.touchlab.crashkios:bugsnag", version.ref = "crashkios-bugsnag" }

[plugins]
android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" }
Expand All @@ -126,8 +127,7 @@ compose = { id = "org.jetbrains.compose", version.ref = "compose" }
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
ksp = { id = 'com.google.devtools.ksp', version.ref = 'ksp' }
buildKonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildKonfig" }
sentry_android = { id = "io.sentry.android.gradle", version.ref = "sentry_android" }
bugsnag = { id = "com.bugsnag.android.gradle", version.ref = "bugsnag-plugin" }

[bundles]
compose = [ "compose_runtime", "compose_foundation", "compose_material", "compose_material3", "compose_resources", "compose_ui", "compose_ui_util", "compose_material_icons_extended" ]
Expand Down
22 changes: 11 additions & 11 deletions iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
7555FF79242A565900829871 /* Resources */,
F85CB1118929364A9C6EFABC /* Frameworks */,
2134C13603D0B299603D9F49 /* [CP] Copy Pods Resources */,
0E668490121D39D1C4498DE3 /* [CP] Embed Pods Frameworks */,
599E3F199C42E8E830BDD65E /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -180,38 +180,38 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
0E668490121D39D1C4498DE3 /* [CP] Embed Pods Frameworks */ = {
2134C13603D0B299603D9F49 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2134C13603D0B299603D9F49 /* [CP] Copy Pods Resources */ = {
599E3F199C42E8E830BDD65E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */ = {
Expand Down
30 changes: 12 additions & 18 deletions iosApp/iosApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import UIKit
import shared
import BackgroundTasks
import Sentry
import Bugsnag

class AppDelegate: NSObject, UIApplicationDelegate {
let rootHolder: RootHolder = RootHolder()
Expand All @@ -19,6 +19,11 @@ class AppDelegate: NSObject, UIApplicationDelegate {
)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
#if !DEBUG
Bugsnag.start()
let config = BugsnagConfiguration.loadConfig()
BugsnagConfigKt.startBugsnag(config: config)
#endif

applicationComponent.initializers
.compactMap { ($0 as! any Initializer) }
Expand Down Expand Up @@ -49,6 +54,8 @@ class AppDelegate: NSObject, UIApplicationDelegate {
}

func cleanUpPosts(task: BGProcessingTask) {
Bugsnag.leaveBreadcrumb(withMessage: "Background Processing")

// Schedule next clean up task 24 hours in future
scheduleCleanUpPosts(earliest: Date(timeIntervalSinceNow: 60 * 60 * 24))

Expand All @@ -63,15 +70,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {
}
task.setTaskCompleted(success: true)
} catch {
let breadcrumb = Breadcrumb()
breadcrumb.level = .info
breadcrumb.category = "Background"

let scope = Scope()
scope.addBreadcrumb(breadcrumb)

SentrySDK.capture(error: error, scope: scope)

Bugsnag.notifyError(error)
task.setTaskCompleted(success: false)
}
}
Expand All @@ -90,6 +89,8 @@ class AppDelegate: NSObject, UIApplicationDelegate {
}

func refreshFeeds(task: BGProcessingTask) {
Bugsnag.leaveBreadcrumb(withMessage: "Background Processing")

scheduledRefreshFeeds(earliest: Date(timeIntervalSinceNow: 60 * 60)) // 1 hour
Task(priority: .background) {
do {
Expand All @@ -101,14 +102,7 @@ class AppDelegate: NSObject, UIApplicationDelegate {

task.setTaskCompleted(success: true)
} catch {
let breadcrumb = Breadcrumb()
breadcrumb.level = .info
breadcrumb.category = "Background"

let scope = Scope()
scope.addBreadcrumb(breadcrumb)

SentrySDK.capture(error: error, scope: scope)
Bugsnag.notifyError(error)
task.setTaskCompleted(success: false)
}
}
Expand Down
5 changes: 5 additions & 0 deletions iosApp/iosApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>bugsnag</key>
<dict>
<key>apiKey</key>
<string>$(BUGSNAG_API_KEY)</string>
</dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>dev.sasikanth.reader.posts_cleanup</string>
Expand Down
Loading
Loading