From 5ab22e742befe2373de8bc6136aa9813334a1094 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 29 Dec 2022 17:30:39 -0500 Subject: [PATCH] Automatically report errors displayed to the user --- Tusker/Views/Toast/ToastConfiguration.swift | 34 +++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Tusker/Views/Toast/ToastConfiguration.swift b/Tusker/Views/Toast/ToastConfiguration.swift index 024bf35b..dbfef76f 100644 --- a/Tusker/Views/Toast/ToastConfiguration.swift +++ b/Tusker/Views/Toast/ToastConfiguration.swift @@ -8,6 +8,7 @@ import UIKit import Pachyderm +import Sentry struct ToastConfiguration { var systemImageName: String? @@ -38,7 +39,7 @@ extension ToastConfiguration { init(from error: Error, with title: String, in viewController: UIViewController, retryAction: ((ToastView) -> Void)?) { self.init(title: title) // localizedDescription is statically dispatched, so we need to call it after the downcast - if let error = error as? Client.Error { + if let error = error as? Pachyderm.Client.Error { self.subtitle = error.localizedDescription self.systemImageName = error.systemImageName self.longPressAction = { [unowned viewController] toast in @@ -54,6 +55,35 @@ extension ToastConfiguration { }) viewController.present(reporter, animated: true) } + // TODO: this is a bizarre place to do this, but code path covers basically all errors + switch error.type { + case .invalidRequest, .invalidResponse, .invalidModel(_), .mastodonError(_): + SentrySDK.capture(error: error) { scope in + let crumb = Breadcrumb(level: .error, category: "error") + crumb.message = title + crumb.data = [ + "request_method": error.requestMethod.name, + "request_endpoint": error.requestEndpoint.description, + ] + switch error.type { + case .invalidRequest: + crumb.data!["error_type"] = "invalid_request" + case .invalidResponse: + crumb.data!["error_type"] = "invalid_response" + case .invalidModel(let error): + crumb.data!["error_type"] = "invalid_model" + crumb.data!["underlying_error"] = String(describing: error) + case .mastodonError(let error): + crumb.data!["error_type"] = "mastodon_error" + crumb.data!["underlying_error"] = error + default: + break + } + scope.add(crumb) + } + default: + break + } } else { self.subtitle = error.localizedDescription self.systemImageName = "exclamationmark.triangle" @@ -73,7 +103,7 @@ extension ToastConfiguration { } } -fileprivate extension Client.Error { +fileprivate extension Pachyderm.Client.Error { var systemImageName: String { switch type { case .networkError(_):