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

Add support for uploading crash reports to Sentry #2605

Merged
merged 13 commits into from
Apr 18, 2024
36 changes: 26 additions & 10 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@
3706FBC7293F65D500E42796 /* EncryptedHistoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7527B263B056C00B973F8 /* EncryptedHistoryStore.swift */; };
3706FBC8293F65D500E42796 /* FirePopoverCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE246F12709EF3B00BEEAEE /* FirePopoverCollectionViewItem.swift */; };
3706FBC9293F65D500E42796 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA61C0D12727F59B00E6B681 /* ArrayExtension.swift */; };
3706FBCA293F65D500E42796 /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; };
3706FBCB293F65D500E42796 /* BookmarkHTMLImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AAF2842C4EA00586521 /* BookmarkHTMLImporter.swift */; };
3706FBCC293F65D500E42796 /* CustomRoundedCornersShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C3CE0128EDC1E70002C24A /* CustomRoundedCornersShape.swift */; };
3706FBCD293F65D500E42796 /* LocaleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */; };
Expand Down Expand Up @@ -1085,6 +1084,9 @@
37CD54D027F2FDD100F1F7B9 /* DefaultBrowserPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C827F2FDD100F1F7B9 /* DefaultBrowserPreferences.swift */; };
37CEFCA92A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CEFCA82A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift */; };
37CEFCAA2A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CEFCA82A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift */; };
37CF91592BB416A500BADCAE /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 37CF91582BB416A500BADCAE /* Crashes */; };
37CF915B2BB416AC00BADCAE /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 37CF915A2BB416AC00BADCAE /* Crashes */; };
37CF915D2BB416B300BADCAE /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 37CF915C2BB416B300BADCAE /* Crashes */; };
37D2377A287EB8CA00BCE03B /* TabIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D23779287EB8CA00BCE03B /* TabIndex.swift */; };
37D2377C287EBDA300BCE03B /* TabIndexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2377B287EBDA300BCE03B /* TabIndexTests.swift */; };
37D23780287EFEE200BCE03B /* PinnedTabsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2377F287EFEE200BCE03B /* PinnedTabsManagerTests.swift */; };
Expand Down Expand Up @@ -1702,7 +1704,6 @@
4B957AD22AC7AE700062CA31 /* FirePopoverCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE246F12709EF3B00BEEAEE /* FirePopoverCollectionViewItem.swift */; };
4B957AD32AC7AE700062CA31 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA61C0D12727F59B00E6B681 /* ArrayExtension.swift */; };
4B957AD42AC7AE700062CA31 /* NetworkProtectionInviteCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */; };
4B957AD52AC7AE700062CA31 /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; };
4B957AD62AC7AE700062CA31 /* BookmarkHTMLImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AAF2842C4EA00586521 /* BookmarkHTMLImporter.swift */; };
4B957AD72AC7AE700062CA31 /* CustomRoundedCornersShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C3CE0128EDC1E70002C24A /* CustomRoundedCornersShape.swift */; };
4B957AD82AC7AE700062CA31 /* LocaleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */; };
Expand Down Expand Up @@ -2682,7 +2683,6 @@
AAC30A26268DFEE200D2D9CD /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */; };
AAC30A28268E045400D2D9CD /* CrashReportReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A27268E045400D2D9CD /* CrashReportReader.swift */; };
AAC30A2A268E239100D2D9CD /* CrashReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A29268E239100D2D9CD /* CrashReport.swift */; };
AAC30A2C268F1ECD00D2D9CD /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; };
AAC30A2E268F1EE300D2D9CD /* CrashReportPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */; };
AAC5E4C725D6A6E8007F5990 /* AddBookmarkPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4C425D6A6E8007F5990 /* AddBookmarkPopover.swift */; };
AAC5E4D025D6A709007F5990 /* Bookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CD25D6A709007F5990 /* Bookmark.swift */; };
Expand Down Expand Up @@ -4409,7 +4409,6 @@
AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporter.swift; sourceTree = "<group>"; };
AAC30A27268E045400D2D9CD /* CrashReportReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportReader.swift; sourceTree = "<group>"; };
AAC30A29268E239100D2D9CD /* CrashReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReport.swift; sourceTree = "<group>"; };
AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportSender.swift; sourceTree = "<group>"; };
AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportPromptPresenter.swift; sourceTree = "<group>"; };
AAC5E4C425D6A6E8007F5990 /* AddBookmarkPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddBookmarkPopover.swift; sourceTree = "<group>"; };
AAC5E4CD25D6A709007F5990 /* Bookmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bookmark.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4853,6 +4852,7 @@
B6EC37FF29B8D915001ACE79 /* Configuration in Frameworks */,
372217822B33380700B8E9C2 /* TestUtils in Frameworks */,
3706FCAA293F65D500E42796 /* UserScript in Frameworks */,
37CF915B2BB416AC00BADCAE /* Crashes in Frameworks */,
3706FCAB293F65D500E42796 /* TrackerRadarKit in Frameworks */,
85E2BBD02B8F534A00DBEC7A /* History in Frameworks */,
4BF97AD52B43C43F00EB4240 /* NetworkProtection in Frameworks */,
Expand Down Expand Up @@ -4970,6 +4970,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
37CF915D2BB416B300BADCAE /* Crashes in Frameworks */,
4B957BD52AC7AE700062CA31 /* QuickLookUI.framework in Frameworks */,
3143C8792B0D1F3D00382627 /* DataBrokerProtection in Frameworks */,
372217842B33380E00B8E9C2 /* TestUtils in Frameworks */,
Expand Down Expand Up @@ -5057,6 +5058,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
37CF91592BB416A500BADCAE /* Crashes in Frameworks */,
373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */,
85E2BBCE2B8F534000DBEC7A /* History in Frameworks */,
1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */,
Expand Down Expand Up @@ -7904,7 +7906,6 @@
children = (
AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */,
AAC30A27268E045400D2D9CD /* CrashReportReader.swift */,
AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */,
AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */,
AAC30A29268E239100D2D9CD /* CrashReport.swift */,
);
Expand Down Expand Up @@ -8939,6 +8940,7 @@
4BCBE4572BA7E17800FC75A1 /* SubscriptionUI */,
85D44B872BA08D30001B4AB5 /* Suggestions */,
4BCBE4592BA7E17800FC75A1 /* Subscription */,
37CF915A2BB416AC00BADCAE /* Crashes */,
9FF521472BAA909C00B9819B /* Lottie */,
);
productName = DuckDuckGo;
Expand Down Expand Up @@ -9229,6 +9231,7 @@
85E2BBD12B8F536F00DBEC7A /* History */,
F1D43AF62B98E48F00BAB743 /* BareBonesBrowserKit */,
85D44B892BA08D3B001B4AB5 /* Suggestions */,
37CF915C2BB416B300BADCAE /* Crashes */,
9FF521492BAA90C400B9819B /* Lottie */,
);
productName = DuckDuckGo;
Expand Down Expand Up @@ -9401,6 +9404,7 @@
1EA7B8D42B7E078C000330A4 /* Subscription */,
F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */,
85D44B852BA08D29001B4AB5 /* Suggestions */,
37CF91582BB416A500BADCAE /* Crashes */,
9FF521452BAA908500B9819B /* Lottie */,
);
productName = DuckDuckGo;
Expand Down Expand Up @@ -10734,7 +10738,6 @@
3706FBC7293F65D500E42796 /* EncryptedHistoryStore.swift in Sources */,
3706FBC8293F65D500E42796 /* FirePopoverCollectionViewItem.swift in Sources */,
3706FBC9293F65D500E42796 /* ArrayExtension.swift in Sources */,
3706FBCA293F65D500E42796 /* CrashReportSender.swift in Sources */,
3706FBCB293F65D500E42796 /* BookmarkHTMLImporter.swift in Sources */,
4BF97ADC2B43C5E200EB4240 /* VPNFeedbackSender.swift in Sources */,
987799F72999996B005D8EB6 /* BookmarkDatabase.swift in Sources */,
Expand Down Expand Up @@ -12000,7 +12003,6 @@
4B957AD22AC7AE700062CA31 /* FirePopoverCollectionViewItem.swift in Sources */,
4B957AD32AC7AE700062CA31 /* ArrayExtension.swift in Sources */,
4B957AD42AC7AE700062CA31 /* NetworkProtectionInviteCodeViewModel.swift in Sources */,
4B957AD52AC7AE700062CA31 /* CrashReportSender.swift in Sources */,
B6BCC5212AFCD9ED002C5499 /* DataImportSourcePicker.swift in Sources */,
4B957AD62AC7AE700062CA31 /* BookmarkHTMLImporter.swift in Sources */,
4B957AD72AC7AE700062CA31 /* CustomRoundedCornersShape.swift in Sources */,
Expand Down Expand Up @@ -12830,7 +12832,6 @@
4B41EDA32B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */,
AA61C0D22727F59B00E6B681 /* ArrayExtension.swift in Sources */,
4B4D60CC2A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */,
AAC30A2C268F1ECD00D2D9CD /* CrashReportSender.swift in Sources */,
373A1AB02842C4EA00586521 /* BookmarkHTMLImporter.swift in Sources */,
B6B5F57F2B024105008DB58A /* DataImportSummaryView.swift in Sources */,
31C3CE0228EDC1E70002C24A /* CustomRoundedCornersShape.swift in Sources */,
Expand Down Expand Up @@ -14499,8 +14500,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 134.0.0;
branch = "dominik/sentry-appstore";
kind = branch;
};
};
9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
Expand Down Expand Up @@ -14739,6 +14740,21 @@
isa = XCSwiftPackageProductDependency;
productName = SyncUI;
};
37CF91582BB416A500BADCAE /* Crashes */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = Crashes;
};
37CF915A2BB416AC00BADCAE /* Crashes */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = Crashes;
};
37CF915C2BB416B300BADCAE /* Crashes */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = Crashes;
};
37DF000429F9C056002B7D3E /* SyncDataProviders */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "bc70d1a27263cc97a4060ac9e73ec10929c28a29",
"version" : "134.0.0"
"branch" : "dominik/sentry-appstore",
"revision" : "21a9a111d64ffb162c44a89f706763d2b8f8b167"
}
},
{
"identity" : "content-scope-scripts",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/content-scope-scripts",
"state" : {
"revision" : "62d5dc3d02f6a8347dc5f0b52162a0107d38b74c",
"version" : "5.8.0"
"revision" : "1bb3bc5eb565735051f342a87b5405d4374876c7",
"version" : "5.12.0"
}
},
{
Expand Down Expand Up @@ -95,8 +95,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/privacy-dashboard",
"state" : {
"revision" : "620921fea14569eb00745cb5a44890d5890d99ec",
"version" : "3.4.0"
"revision" : "14b13d0c3db38f471ce4ba1ecb502ee1986c84d7",
"version" : "3.5.0"
}
},
{
Expand Down
21 changes: 20 additions & 1 deletion DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import Combine
import Common
import Configuration
import CoreData
import Crashes
import DDGSync
import History
import MetricKit
import Networking
import Persistence
import PixelKit
Expand Down Expand Up @@ -64,9 +66,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

let fileStore: FileStore

#if APPSTORE
private let crashCollection = CrashCollection(platform: .macOSAppStore, log: .default)
#else
private let crashReporter = CrashReporter()
#endif

private(set) var stateRestorationManager: AppStateRestorationManager!
private var grammarFeaturesManager = GrammarFeaturesManager()
private let crashReporter = CrashReporter()
let internalUserDecider: InternalUserDecider
let featureFlagger: FeatureFlagger
private var appIconChanger: AppIconChanger!
Expand Down Expand Up @@ -284,7 +291,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

applyPreferredTheme()

#if APPSTORE
crashCollection.start { pixelParameters, payloads, completion in
pixelParameters.forEach { _ in Pixel.fire(.crash) }
guard let lastPayload = payloads.last else {
return
}
DispatchQueue.main.async {
CrashReportPromptPresenter().showPrompt(for: lastPayload, userDidAllowToReport: completion)
}
}
#else
crashReporter.checkForNewReports()
#endif

urlEventHandler.applicationDidFinishLaunching()

Expand Down
15 changes: 13 additions & 2 deletions DuckDuckGo/CrashReports/Model/CrashReport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
//

import Foundation
import MetricKit

protocol CrashReport {
protocol CrashReportPresenting {
var content: String? { get }
}

protocol CrashReport: CrashReportPresenting {

static var fileExtension: String { get }

var url: URL { get }
var content: String? { get }
var contentData: Data? { get }

}
Expand Down Expand Up @@ -91,3 +95,10 @@ struct JSONCrashReport: CrashReport {
}

}

@available(macOS 12.0, *)
extension MXDiagnosticPayload: CrashReportPresenting {
var content: String? {
jsonRepresentation().utf8String()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ final class CrashReportPromptPresenter {
// swiftlint:enable force_cast
}

func showPrompt(_ delegate: CrashReportPromptViewControllerDelegate, for crashReport: CrashReport) {
viewController.delegate = delegate
func showPrompt(for crashReport: CrashReportPresenting, userDidAllowToReport: @escaping () -> Void) {
viewController.crashReport = crashReport
viewController.userDidAllowToReport = userDidAllowToReport

windowController.showWindow(self)
windowController.window?.center()
Expand Down
45 changes: 0 additions & 45 deletions DuckDuckGo/CrashReports/Model/CrashReportSender.swift
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to BSK

This file was deleted.

36 changes: 12 additions & 24 deletions DuckDuckGo/CrashReports/Model/CrashReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
// limitations under the License.
//

import Common
import Crashes
import Foundation

final class CrashReporter {

private let reader = CrashReportReader()
private lazy var sender = CrashReportSender()
private lazy var sender = CrashReportSender(platform: .macOS, log: .default)
private lazy var promptPresenter = CrashReportPromptPresenter()

@UserDefaultsWrapper(key: .lastCrashReportCheckDate, defaultValue: nil)
private var lastCheckDate: Date?

private var latestCrashReport: CrashReport?

func checkForNewReports() {

#if !DEBUG
Expand All @@ -49,29 +49,17 @@ final class CrashReporter {

Pixel.fire(.crash)

latestCrashReport = latest
promptPresenter.showPrompt(self, for: latest)

#endif

}

}

extension CrashReporter: CrashReportPromptViewControllerDelegate {

func crashReportPromptViewController(_ crashReportPromptViewController: CrashReportPromptViewController,
userDidAllowToReport: Bool) {
guard userDidAllowToReport else {
return
promptPresenter.showPrompt(for: latest) {
guard let contentData = latest.contentData else {
assertionFailure("CrashReporter: Can't get the content of the crash report")
return
}
Task {
await self.sender.send(contentData)
}
}

guard let latestCrashReport = latestCrashReport else {
assertionFailure("CrashReporter: The latest crash report is nil")
return
}
#endif

sender.send(latestCrashReport)
}

}
Loading
Loading