More thorough error logging (#1297)

* Data is required for .logError

* Edit data for readability

* remove commented out breadcrumbs

---------

Co-authored-by: ggurdin <ggurdin@gmail.com>
Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com>
pull/1544/head
Kelrap 11 months ago committed by GitHub
parent eed93f2601
commit dc79b98ea6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -638,6 +638,7 @@ class ChatListController extends State<ChatList>
m: "Failed to join analytics room",
e: err,
s: s,
data: {"analyticsRoom": analyticsRoom?.id},
);
}
return;

@ -97,7 +97,18 @@ class AlternativeTranslator {
translationFeedbackKey = FeedbackKey.othersAreBetter;
} catch (err, stack) {
if (err is! http.Response) {
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"sourceText": choreographer.itController.sourceText,
"currentText": choreographer.currentText,
"userL1": choreographer.l1LangCode,
"userL2": choreographer.l2LangCode,
"goldRouteTranslation":
choreographer.itController.goldRouteTracker.fullTranslation,
},
);
}
choreographer.errorService.setError(
ChoreoError(type: ChoreoErrorType.unknown, raw: err),

@ -289,7 +289,21 @@ class Choreographer {
onlyTokensAndLanguageDetection: onlyTokensAndLanguageDetection,
));
} catch (err, stack) {
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"l2Lang": l2Lang?.toJson(),
"l1Lang": l1Lang?.toJson(),
"choreoMode": choreoMode,
"igcEnabled": igcEnabled,
"itEnabled": itEnabled,
"isAutoIGCEnabled": isAutoIGCEnabled,
"isTranslationDone": itController.isTranslationDone,
"onlyTokensAndLanguageDetection": onlyTokensAndLanguageDetection,
"useCustomInput": _useCustomInput,
},
);
} finally {
stopLoading();
}
@ -317,6 +331,10 @@ class Choreographer {
ErrorHandler.logError(
e: "onReplacementSelect with null igcTextData",
s: StackTrace.current,
data: {
"matchIndex": matchIndex,
"choiceIndex": choiceIndex,
},
);
MatrixState.pAnyState.closeOverlay();
return;
@ -325,6 +343,11 @@ class Choreographer {
ErrorHandler.logError(
e: "onReplacementSelect with null choices",
s: StackTrace.current,
data: {
"igctextData": igc.igcTextData?.toJson(),
"matchIndex": matchIndex,
"choiceIndex": choiceIndex,
},
);
MatrixState.pAnyState.closeOverlay();
return;
@ -363,16 +386,15 @@ class Choreographer {
setState();
} catch (err, stack) {
debugger(when: kDebugMode);
Sentry.addBreadcrumb(
Breadcrumb.fromJson(
{
"igctextDdata": igc.igcTextData?.toJson(),
"matchIndex": matchIndex,
"choiceIndex": choiceIndex,
},
),
ErrorHandler.logError(
e: err,
s: stack,
data: {
"igctextData": igc.igcTextData?.toJson(),
"matchIndex": matchIndex,
"choiceIndex": choiceIndex,
},
);
ErrorHandler.logError(e: err, s: stack);
igc.igcTextData?.matches.clear();
} finally {
giveInputFocus();
@ -387,6 +409,7 @@ class Choreographer {
ErrorHandler.logError(
m: "should not be in onIgnoreMatch with null igcTextData",
s: StackTrace.current,
data: {},
);
return;
}
@ -397,7 +420,7 @@ class Choreographer {
if (matchIndex == -1) {
debugger(when: kDebugMode);
throw Exception("Cannnot find the ignored match in igcTextData");
throw Exception("Cannot find the ignored match in igcTextData");
}
igc.igcTextData!.matches[matchIndex].status = PangeaMatchStatus.ignored;
@ -417,6 +440,9 @@ class Choreographer {
ErrorHandler.logError(
e: err,
s: stack,
data: {
"igctextData": igc.igcTextData?.toJson(),
},
);
igc.igcTextData?.matches.clear();
} finally {

@ -120,7 +120,19 @@ class IgcController {
choreographer.errorService.setError(
ChoreoError(type: ChoreoErrorType.unknown, raw: err),
);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"onlyTokensAndLanguageDetection": onlyTokensAndLanguageDetection,
"currentText": choreographer.currentText,
"userL1": choreographer.l1LangCode,
"userL2": choreographer.l2LangCode,
"igcEnabled": choreographer.igcEnabled,
"itEnabled": choreographer.itEnabled,
"matches": igcTextData?.matches.map((e) => e.toJson()),
},
);
clear();
}
}
@ -129,8 +141,11 @@ class IgcController {
if (igcTextData == null || igcTextData!.matches.isEmpty) {
debugger(when: kDebugMode);
ErrorHandler.logError(
m: "should not be calling showFirstMatch with this igcTextData ${igcTextData?.toJson().toString()}",
m: "should not be calling showFirstMatch with this igcTextData.",
s: StackTrace.current,
data: {
"igcTextData": igcTextData?.toJson(),
},
);
return;
}

@ -175,7 +175,15 @@ class ITController {
} catch (e, s) {
debugger(when: kDebugMode);
if (e is! http.Response) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"currentText": choreographer.currentText,
"sourceText": sourceText,
"currentITStepPayloadID": currentITStep?.payloadId,
},
);
}
choreographer.errorService.setErrorAndLock(
ChoreoError(type: ChoreoErrorType.unknown, raw: e),
@ -191,8 +199,8 @@ class ITController {
e: Exception("sourceText is null in getNextTranslationData"),
data: {
"sourceText": sourceText,
"currentITStep": currentITStep,
"nextITStep": nextITStep,
"currentITStepPayloadID": currentITStep?.payloadId,
"continuances": goldRouteTracker.continuances.map((e) => e.toJson()),
},
);
return;
@ -220,7 +228,16 @@ class ITController {
} catch (e, s) {
debugger(when: kDebugMode);
if (e is! http.Response) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"sourceText": sourceText,
"currentITStepPayloadID": currentITStep?.payloadId,
"continuances":
goldRouteTracker.continuances.map((e) => e.toJson()),
},
);
}
choreographer.errorService.setErrorAndLock(
ChoreoError(type: ChoreoErrorType.unknown, raw: e),
@ -246,7 +263,14 @@ class ITController {
} catch (err, stack) {
debugger(when: kDebugMode);
if (err is! http.Response) {
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"newSourceText": newSourceText,
"l1Lang": choreographer.l1LangCode,
},
);
}
choreographer.errorService.setErrorAndLock(
ChoreoError(type: ChoreoErrorType.unknown, raw: err),

@ -301,7 +301,10 @@ class ITChoices extends StatelessWidget {
String? get sourceText {
if ((controller.sourceText == null || controller.sourceText!.isEmpty)) {
ErrorHandler.logError(m: "null source text in ItChoices");
ErrorHandler.logError(
m: "null source text in ItChoices",
data: {},
);
}
return controller.sourceText;
}
@ -316,6 +319,9 @@ class ITChoices extends StatelessWidget {
ErrorHandler.logError(
m: "currentITStep is null in showCard",
s: StackTrace.current,
data: {
"index": index,
},
);
return;
}

@ -66,6 +66,7 @@ class ITFeedbackCardController extends State<ITFeedbackCard> {
if (res == null) {
ErrorHandler.logError(
m: "Cannot translate feedback because res is null",
data: {},
);
return;
}

@ -76,6 +76,7 @@ class LanguagePermissionsButtons extends StatelessWidget {
if (roomID == null) {
ErrorHandler.logError(
e: Exception("Room ID is null in language permissions"),
data: {},
);
return null;
}
@ -140,6 +141,9 @@ class LanguagePermissionsButtons extends StatelessWidget {
debugger(when: kDebugMode);
ErrorHandler.logError(
e: Exception("Unhandled case in language permissions"),
data: {
"roomID": roomID,
},
);
return null;
}

@ -21,7 +21,14 @@ class TranslationFeedback extends StatelessWidget {
feedbackText = "Nice job!";
style = null;
debugPrint("error getting copy and styles");
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"feedbackText": controller.choreographer.altTranslator
.translationFeedback(context),
},
);
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),

@ -37,7 +37,13 @@ class ClassController extends BaseController {
Future.wait(
_pangeaController.matrixState.client.spacesImTeaching.map(
(space) => space.setClassPowerLevels().catchError((err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"spaceID": space.id,
},
);
}),
),
);
@ -173,7 +179,13 @@ class ClassController extends BaseController {
);
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"roomID": roomId,
},
);
}
}
}

@ -104,6 +104,10 @@ class _ContextualDefinitionRepo {
e: Exception(
"empty text in contextual definition response",
),
data: {
"request": request.toJson(),
"accessToken": accessToken,
},
);
}

@ -80,7 +80,11 @@ class GetAnalyticsController {
..._locallyCachedConstructs,
]);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
} finally {
_updateAnalyticsStream();
if (!initCompleter.isCompleted) initCompleter.complete();
@ -130,7 +134,13 @@ class GetAnalyticsController {
formattedCache[entry.key] =
entry.value.map((e) => OneConstructUse.fromJson(e)).toList();
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"key": entry.key,
},
);
continue;
}
}
@ -148,6 +158,9 @@ class GetAnalyticsController {
),
s: stackTrace,
m: 'Failed to retrieve messages since update',
data: {
"messagesSinceUpdate": PLocalKey.messagesSinceUpdate,
},
);
return {};
}

@ -104,6 +104,10 @@ class _ITFeedbackRepo {
e: Exception(
"empty text in contextual definition response",
),
data: {
"request": request.toJson(),
"accessToken": accessToken,
},
);
}

@ -44,7 +44,13 @@ class PangeaLanguage {
_langList.insert(0, LanguageModel.multiLingual());
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"langList": _langList.map((e) => e.toJson()),
},
);
}
}

@ -80,6 +80,10 @@ class MessageDataController extends BaseController {
e: Exception(
"empty tokens in tokenize response return",
),
data: {
"accessToken": accessToken,
"request": request.toJson(),
},
);
}

@ -290,7 +290,14 @@ class PangeaController {
return null;
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"directChatRoomId": matrixState.client
.getDirectChatFromUserId(BotName.byEnvironment),
},
);
}
}
@ -370,6 +377,9 @@ class PangeaController {
} catch (err) {
ErrorHandler.logError(
e: "Failed to fetch participants for space ${space.id}",
data: {
"spaceID": space.id,
},
);
continue;
}

@ -96,6 +96,7 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
s: s,
e: err,
m: "Failed to get last updated time for analytics",
data: {},
);
} finally {
// if this is the initial load, complete the lastUpdatedCompleter
@ -254,6 +255,9 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
e: PangeaWarningError("Failed to add message since update: $e"),
s: s,
m: 'Failed to add message since update for eventId: $cacheKey',
data: {
"cacheKey": cacheKey,
},
);
}
}
@ -368,6 +372,9 @@ class PutAnalyticsController extends BaseController<AnalyticsStream> {
e: err,
m: "Failed to update analytics",
s: s,
data: {
"l2Override": l2Override,
},
);
} finally {
_updateCompleter?.complete();

@ -113,7 +113,14 @@ class SpeechToTextController {
final response = SpeechToTextModel.fromJson(json);
saveSpeechToTextAsRepresentationEvent(response, requestModel).onError(
(error, stackTrace) => ErrorHandler.logError(e: error, s: stackTrace),
(error, stackTrace) => ErrorHandler.logError(
e: error,
s: stackTrace,
data: {
"response": response.toJson(),
"requestModel": requestModel.toJson(),
},
),
);
return response;

@ -135,7 +135,13 @@ class SubscriptionController extends BaseController {
setState(null);
} catch (e, s) {
debugPrint("Failed to initialize subscription controller");
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"availableSubscriptionInfo": availableSubscriptionInfo?.toJson(),
},
);
}
}
@ -155,6 +161,9 @@ class SubscriptionController extends BaseController {
ErrorHandler.logError(
m: "Tried to subscribe to web SubscriptionDetails with Null duration",
s: StackTrace.current,
data: {
"selectedSubscription": selectedSubscription.toJson(),
},
);
return;
}
@ -177,6 +186,9 @@ class SubscriptionController extends BaseController {
ErrorHandler.logError(
m: "Tried to subscribe to SubscriptionDetails with Null revenuecat Package",
s: StackTrace.current,
data: {
"selectedSubscription": selectedSubscription.toJson(),
},
);
return;
}
@ -198,6 +210,9 @@ class SubscriptionController extends BaseController {
ErrorHandler.logError(
m: "Failed to purchase revenuecat package for user $_userID with error code $errCode",
s: StackTrace.current,
data: {
"selectedSubscription": selectedSubscription.toJson(),
},
);
return;
}
@ -230,8 +245,9 @@ class SubscriptionController extends BaseController {
final DateTime? createdAt = _userController.profile.userSettings.createdAt;
if (createdAt == null) {
ErrorHandler.logError(
m: "Null user profile createAt in subscription settings",
m: "Null user profile createdAt in subscription settings",
s: StackTrace.current,
data: {},
);
return;
}
@ -329,7 +345,13 @@ class SubscriptionController extends BaseController {
);
dismissPaywall();
} catch (e, s) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"availableSubscriptionInfo": availableSubscriptionInfo?.toJson(),
},
);
}
}

@ -115,7 +115,11 @@ class UserController extends BaseController {
await _initialize();
addProfileListener();
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
} finally {
_profileCompleter!.complete();
}
@ -159,6 +163,7 @@ class UserController extends BaseController {
if (userId == null) {
ErrorHandler.logError(
e: "calling fullname with userId == null",
data: {},
);
return null;
}
@ -173,7 +178,11 @@ class UserController extends BaseController {
await initialize();
return profile.userSettings.targetLanguage != null;
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
return false;
}
}
@ -208,7 +217,11 @@ class UserController extends BaseController {
srcLang != LanguageKeys.unknownLanguage &&
tgtLang != LanguageKeys.unknownLanguage;
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
return false;
}
}

@ -22,8 +22,14 @@ extension AnalyticsClientExtension on Client {
analyticsRoom.membership == Membership.invite) {
debugger(when: kDebugMode);
analyticsRoom.join().onError(
(error, stackTrace) =>
ErrorHandler.logError(e: error, s: stackTrace),
(error, stackTrace) => ErrorHandler.logError(
e: error,
s: stackTrace,
data: {
"langCode": langCode,
"userIdParam": userIdParam,
},
),
);
return analyticsRoom;
}
@ -137,7 +143,13 @@ extension AnalyticsClientExtension on Client {
)
.map(
(room) => room.join().catchError((err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"roomID": room.id,
},
);
}),
),
);

@ -60,6 +60,7 @@ extension PangeaEvent on Event {
if (transcription == null || audioContent == null) {
ErrorHandler.logError(
e: "Called getPangeaAudioFile on an audio message without transcription or audio content",
data: {},
);
return null;
}

@ -29,6 +29,10 @@ extension AnalyticsRoomExtension on Room {
e: err,
m: "Failed to join analytics room $roomID in space $id",
s: s,
data: {
"roomID": roomID,
"spaceID": id,
},
);
}),
),
@ -37,6 +41,9 @@ extension AnalyticsRoomExtension on Room {
ErrorHandler.logError(
e: err,
s: s,
data: {
"spaceID": id,
},
);
return;
}
@ -112,6 +119,10 @@ extension AnalyticsRoomExtension on Room {
e: err,
m: "Failed to invite teacher ${teacher.id} to analytics room ${analyticsRoom.id}",
s: s,
data: {
"teacherID": teacher.id,
"analyticsRoomID": analyticsRoom.id,
},
);
}),
),

@ -129,6 +129,10 @@ extension ChildrenAndParentsRoomExtension on Room {
ErrorHandler.logError(
e: e,
m: 'Failed to remove child from parent',
data: {
"roomID": roomId,
"parentID": parent.id,
},
);
}
}
@ -141,7 +145,15 @@ extension ChildrenAndParentsRoomExtension on Room {
visibility: matrix.Visibility.private,
);
} catch (err, stack) {
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"roomID": roomId,
"childID": child.id,
"suggested": suggested,
},
);
}
}

@ -130,7 +130,15 @@ extension EventsRoomExtension on Room {
await leave();
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack, data: powerLevels);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"powerLevel": client.userID != null
? getPowerLevelByUserId(client.userID!)
: null,
},
);
rethrow;
}
},

@ -29,7 +29,13 @@ extension RoomSettingsRoomExtension on Room {
data: {"room": toJson()},
),
);
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"roomID": id,
},
);
return null;
}
}
@ -109,6 +115,10 @@ extension RoomSettingsRoomExtension on Room {
ErrorHandler.logError(
e: "Failed to fetch suggestion status of room $id in space ${space.id}",
s: StackTrace.current,
data: {
"spaceID": space.id,
"roomID": id,
},
);
return true;
}
@ -121,6 +131,11 @@ extension RoomSettingsRoomExtension on Room {
ErrorHandler.logError(
e: "Failed to set suggestion status of room $id in space ${space.id}",
s: StackTrace.current,
data: {
"spaceID": space.id,
"roomID": id,
"suggest": suggest,
},
);
return;
}

@ -26,7 +26,13 @@ class ChoreoEvent {
return _content;
} catch (err, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"event": event.toJson(),
},
);
return null;
}
}

@ -39,6 +39,9 @@ class PangeaMessageEvent {
debugger(when: kDebugMode);
ErrorHandler.logError(
m: "${event.type} should not be used to make a PangeaMessageEvent",
data: {
"event": event.toJson(),
},
);
}
_event = event;
@ -192,7 +195,7 @@ class PangeaMessageEvent {
ErrorHandler.logError(
e: e,
s: s,
data: event.content.tryGetMap(ModelKey.transcription),
data: {},
m: "error parsing data in getTextToSpeechLocal",
);
return false;
@ -333,7 +336,7 @@ class PangeaMessageEvent {
ErrorHandler.logError(
e: e,
s: s,
data: content,
data: content ?? {},
m: "error parsing tokensSent",
);
return null;
@ -392,6 +395,9 @@ class PangeaMessageEvent {
m: "error parsing originalSent",
e: err,
s: s,
data: {
"event": _event.toJson(),
},
);
}
}
@ -417,6 +423,9 @@ class PangeaMessageEvent {
m: "error parsing originalWritten",
e: err,
s: s,
data: {
"event": _event.toJson(),
},
);
}
}
@ -633,7 +642,13 @@ class PangeaMessageEvent {
try {
return practiceActivities.isNotEmpty;
} catch (e, s) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"event": _event.toJson(),
},
);
return false;
}
}

@ -85,16 +85,14 @@ class RepresentationEvent {
if (tokenEvents.length > 1) {
debugger(when: kDebugMode);
Sentry.addBreadcrumb(
Breadcrumb(
message: "Token events for representation ${_event?.eventId}: "
"Content: ${tokenEvents.map((e) => e.content).toString()}"
"Type: ${tokenEvents.map((e) => e.type).toString()}",
),
);
ErrorHandler.logError(
m: 'should not have more than one tokenEvent per representation ${_event?.eventId}',
s: StackTrace.current,
data: {
"eventID": _event?.eventId,
"content": tokenEvents.map((e) => e.content).toString(),
"type": tokenEvents.map((e) => e.type).toString(),
},
);
}
@ -180,7 +178,7 @@ class RepresentationEvent {
ErrorHandler.logError(
m: 'should not have more than one choreoEvent per representation ${_event?.eventId}',
s: StackTrace.current,
data: _event?.toJson(),
data: {"event": _event?.toJson()},
);
}

@ -26,7 +26,13 @@ class TokensEvent {
return _content!;
} catch (err, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"event": event.toJson(),
},
);
return null;
}
}

@ -6,7 +6,6 @@ import 'package:fluffychat/pangea/models/analytics/construct_use_model.dart';
import 'package:fluffychat/pangea/models/analytics/constructs_model.dart';
import 'package:fluffychat/pangea/models/practice_activities.dart/practice_activity_model.dart';
import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
/// A wrapper around a list of [OneConstructUse]s, used to simplify
/// the process of filtering / sorting / displaying the events.
@ -59,7 +58,13 @@ class ConstructListModel {
_updateCategoriesToUses();
_updateMetrics();
} catch (err, s) {
ErrorHandler.logError(e: "Failed to update analytics: $err", s: s);
ErrorHandler.logError(
e: "Failed to update analytics: $err",
s: s,
data: {
"newUses": newUses.map((e) => e.toJson()),
},
);
}
}
@ -159,16 +164,14 @@ class ConstructListModel {
level = levelCalculation.floor();
} else {
level = 1;
Sentry.addBreadcrumb(
Breadcrumb(
data: {
"totalXP": totalXP,
"prevXP": prevXP,
"level": levelCalculation,
},
),
ErrorHandler.logError(
e: "Calculated level in Nan or Infinity",
data: {
"totalXP": totalXP,
"prevXP": prevXP,
"level": levelCalculation,
},
);
ErrorHandler.logError(e: "Calculated level in Nan or Infinity");
}
}

@ -32,14 +32,25 @@ class ConstructAnalyticsModel {
try {
uses.add(OneConstructUse.fromJson(useJson));
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"useJson": useJson,
},
);
continue;
}
}
}
} else {
debugger(when: kDebugMode);
ErrorHandler.logError(m: "Analytics room with non-list uses");
ErrorHandler.logError(
m: "Analytics room with non-list uses",
data: {
"usesKey": _usesKey,
},
);
}
return ConstructAnalyticsModel(
@ -172,6 +183,9 @@ class OneConstructUse {
}
ErrorHandler.logError(
m: "Morph construct lemma $morphLemma not found in morph categories and labels",
data: {
"morphLemma": morphLemma,
},
);
return "Other";
}

@ -127,7 +127,13 @@ class AvailableSubscriptionsInfo {
try {
return AvailableSubscriptionsInfo.fromJson(json);
} catch (e, s) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"json": json,
},
);
return null;
}
}

@ -122,7 +122,11 @@ class BotOptionsModel {
return data;
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: data,
);
return data;
}
}

@ -11,7 +11,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../constants/model_keys.dart';
@ -127,6 +126,9 @@ class IGCTextData {
debugger(when: kDebugMode);
ErrorHandler.logError(
m: "pangeaMatch.match.choices is null in acceptReplacement",
data: {
"match": pangeaMatch.match.toJson(),
},
);
return;
}
@ -268,16 +270,12 @@ class IGCTextData {
final spaceBetween = tokens[tokenIndex + 1].text.offset - endOfToken;
if (spaceBetween < 0) {
Sentry.addBreadcrumb(
Breadcrumb.fromJson(
{
"fullText": originalInput,
"tokens": tokens.map((e) => e.toJson()).toString(),
},
),
);
ErrorHandler.logError(
m: "weird token lengths for ${tokens[tokenIndex].text.content} and ${tokens[tokenIndex + 1].text.content}",
data: {
"fullText": originalInput,
"tokens": tokens.map((e) => e.toJson()).toString(),
},
);
return 0;
}

@ -481,7 +481,13 @@ class LanguageModel {
return L10n.of(context).shDisplayName;
}
debugger(when: kDebugMode);
ErrorHandler.logError(m: "No Display name found", s: StackTrace.current);
ErrorHandler.logError(
m: "No Display name found",
s: StackTrace.current,
data: {
"langCode": langCode,
},
);
return null;
}
}

@ -29,6 +29,7 @@ class MobileSubscriptionInfo extends CurrentSubscriptionInfo {
ErrorHandler.logError(
m: "Failed to configure revenuecat SDK",
s: StackTrace.current,
data: {},
);
}
}
@ -66,6 +67,7 @@ class MobileSubscriptionInfo extends CurrentSubscriptionInfo {
ErrorHandler.logError(
m: "Failed to fetch revenuecat customer info",
s: StackTrace.current,
data: {},
);
return;
}

@ -57,7 +57,11 @@ class LanguageSettingsModel {
return data;
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: data,
);
return data;
}
}

@ -71,7 +71,11 @@ class PangeaSsoButtonState extends State<PangeaSsoButton> {
context,
);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
if (err is MatrixException) {
_error = err.errorMessage;
} else {

@ -119,7 +119,17 @@ class FindPartnerController extends State<FindPartner> {
} catch (err, s) {
error = err.toString();
setState(() => loading = false);
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"accessToken": pangeaController.userController.accessToken,
"targetLanguage": targetLanguageSearch.langCode,
"sourceLanguage": sourceLanguageSearch.langCode,
"country": countrySearch,
"pageNumber": nextPage.toString(),
},
);
return;
}

@ -185,13 +185,21 @@ class SignupPageController extends State<SignupPage> {
}
} on MatrixException catch (e, s) {
if (e.error != MatrixError.M_THREEPID_IN_USE) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
}
error = e.errorMessage;
} catch (e, s) {
const cancelledString = "Exception: Request has been canceled";
if (e.toString() != cancelledString) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
}
error = (e).toLocalizedString(context);
} finally {

@ -130,7 +130,13 @@ class UserSettingsState extends State<UserSettingsPage> {
}
if (file != null) await client.setAvatar(file);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"avatar": avatar.toString(),
},
);
}
}

@ -37,6 +37,10 @@ class ContextualizationTranslationRepo {
e: Exception(
"empty translations in contextual translation response return",
),
data: {
"accessToken": accessToken,
"request": request.toJson(),
},
);
}

@ -31,6 +31,7 @@ class SubscriptionRepo {
ErrorHandler.logError(
m: "Failed to fetch app information for revenuecat API",
s: StackTrace.current,
data: {},
);
return null;
}
@ -50,7 +51,11 @@ class SubscriptionRepo {
RCProductsResponseModel.fromJson(json);
return resp.allProducts;
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
return null;
}
}

@ -25,7 +25,11 @@ class BotStyle {
return existingStyle?.merge(botStyle) ?? botStyle;
} catch (err, stack) {
ErrorHandler.logError(m: "error getting styles", s: stack);
ErrorHandler.logError(
m: "error getting styles",
s: stack,
data: {},
);
return existingStyle ?? const TextStyle();
}
}

@ -41,7 +41,13 @@ Future<void> downloadChat(
room,
);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"roomID": room.id,
},
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
@ -210,7 +216,11 @@ Future<void> downloadFile(
}
} catch (err, s) {
debugPrint("Failed to get download folder path");
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
}
if (directory != null) {
final File f = File("${directory.path}/$filename");

@ -44,7 +44,11 @@ class ErrorHandler {
};
PlatformDispatcher.instance.onError = (exception, stack) {
logError(e: exception, s: stack);
logError(
e: exception,
s: stack,
data: {},
);
return true;
};
}
@ -53,7 +57,7 @@ class ErrorHandler {
Object? e,
StackTrace? s,
String? m,
Map<String, dynamic>? data,
required Map<String, dynamic> data,
SentryLevel level = SentryLevel.error,
}) async {
if (e is PangeaWarningError) {
@ -63,10 +67,8 @@ class ErrorHandler {
if (m != null) debugPrint("error message: $m");
}
if (data != null) {
Sentry.addBreadcrumb(Breadcrumb.fromJson(data));
debugPrint(data.toString());
}
Sentry.addBreadcrumb(Breadcrumb.fromJson(data));
debugPrint(data.toString());
Sentry.captureException(
e ?? Exception(m ?? "no message supplied"),
@ -101,17 +103,12 @@ class ErrorCopy {
if (error is http.Response) {
errorCode = (error as http.Response).statusCode;
} else {
ErrorHandler.logError(e: error, s: StackTrace.current);
errorCode = null;
}
if (L10n.of(context) == null) {
_setDefaults();
Sentry.addBreadcrumb(Breadcrumb.fromJson({"error": error?.toString()}));
ErrorHandler.logError(
m: "null L10n in ErrorCopy.setCopy",
e: error,
s: StackTrace.current,
data: {},
);
return;
errorCode = null;
}
final L10n l10n = L10n.of(context);
@ -155,7 +152,11 @@ class ErrorCopy {
body = l10n.errorPleaseRefresh;
}
} catch (e, s) {
ErrorHandler.logError(e: s, s: s);
ErrorHandler.logError(
e: s,
s: s,
data: {},
);
_setDefaults();
}
}

@ -103,7 +103,13 @@ class GetChatListItemSubtitle {
return text;
} catch (e, s) {
// debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"event": event?.toJson(),
},
);
return event?.body ?? l10n.emptyChat;
}
}

@ -8,7 +8,6 @@ import '../controllers/pangea_controller.dart';
import '../widgets/common/bot_face_svg.dart';
import '../widgets/igc/card_header.dart';
import 'bot_style.dart';
import 'error_handler.dart';
import 'overlay.dart';
class InstructionsController {
@ -94,13 +93,6 @@ class InstructionsController {
if (key.toggledOff() && !forceShow) {
return;
}
if (L10n.of(context) == null) {
ErrorHandler.logError(
m: "null context in ITBotButton.showCard",
s: StackTrace.current,
);
return;
}
final botStyle = BotStyle.text(context);
Future.delayed(

@ -6,7 +6,6 @@ import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../constants/match_rule_ids.dart';
import '../models/pangea_match_model.dart';
@ -65,15 +64,13 @@ class MatchCopy {
}
} catch (err, stack) {
debugger(when: kDebugMode);
Sentry.addBreadcrumb(
Breadcrumb(
message: "match",
data: {
"match": match.toJson(),
},
),
ErrorHandler.logError(
e: err,
s: stack,
data: {
"match": match.toJson(),
},
);
ErrorHandler.logError(e: err, s: stack);
_setDefaults();
}
}
@ -217,15 +214,13 @@ class MatchCopy {
}
} catch (err, stack) {
debugger(when: kDebugMode);
Sentry.addBreadcrumb(
Breadcrumb(
message: "match",
data: {
"match": match.toJson(),
},
),
ErrorHandler.logError(
e: err,
s: stack,
data: {
"match": match.toJson(),
},
);
ErrorHandler.logError(e: err, s: stack);
_setDefaults();
}
}

@ -74,7 +74,11 @@ class OverlayUtil {
.openOverlay(entry, context, closePrevOverlay: closePrevOverlay);
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {},
);
}
}
@ -145,7 +149,11 @@ class OverlayUtil {
);
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {},
);
}
}

@ -43,7 +43,11 @@ class PLoadingStatusStateV2 extends State<PLoadingStatusV2> {
widget.onFinish?.call();
}
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
isFinished = true;
}
}

@ -14,6 +14,7 @@ Future<bool> showUpdateVersionDialog({
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
await showOkAlertDialog(
context: context,

@ -157,7 +157,13 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
);
}
} catch (e, s) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"eventID": pangeaMessageEvent?.eventId,
},
);
} finally {
if (_selectedTargetTokenForWordMeaning != null) {
messageAnalyticsEntry?.addForWordMeaning(
@ -214,6 +220,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
ErrorHandler.logError(
e: "Error calling setState in MessageSelectionOverlay: $e",
s: s,
data: {},
);
}
} else {
@ -225,6 +232,7 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
ErrorHandler.logError(
e: "Error calling setState in MessageSelectionOverlay after postframeCallback: $e",
s: s,
data: {},
);
}
});
@ -468,7 +476,13 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
widget._event.eventId,
);
} catch (e, s) {
ErrorHandler.logError(e: "Error getting message render box: $e", s: s);
ErrorHandler.logError(
e: "Error getting message render box: $e",
s: s,
data: {
"eventID": widget._event.eventId,
},
);
return null;
}
}
@ -481,7 +495,11 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
try {
return _messageRenderBox?.size;
} catch (e, s) {
ErrorHandler.logError(e: "Error getting message size: $e", s: s);
ErrorHandler.logError(
e: "Error getting message size: $e",
s: s,
data: {},
);
return null;
}
}
@ -513,7 +531,11 @@ class MessageOverlayController extends State<MessageSelectionOverlay>
try {
return MediaQuery.of(context);
} catch (e, s) {
ErrorHandler.logError(e: "Error getting media query: $e", s: s);
ErrorHandler.logError(
e: "Error getting media query: $e",
s: s,
data: {},
);
return null;
}
}

@ -142,7 +142,11 @@ class MessageSpeechToTextCardState extends State<MessageSpeechToTextCard> {
return TextSpan(children: spans);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
setState(() => error = err);
return const TextSpan(text: '');
}

@ -99,7 +99,10 @@ class MessageTranslationCardState extends State<MessageTranslationCard> {
? fetchSelectedTextTranslation()
: fetchRepresentationText());
} catch (err) {
ErrorHandler.logError(e: err);
ErrorHandler.logError(
e: err,
data: {},
);
}
if (mounted) {

@ -77,7 +77,11 @@ class TtsController {
}
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
} finally {
debugPrint("availableLangCodes: $_availableLangCodes");
final enableTTSSetting = userController.profile.toolSettings.enableTTS;
@ -114,7 +118,11 @@ class TtsController {
}
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
}
}
@ -135,7 +143,11 @@ class TtsController {
}
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
}
}
@ -177,7 +189,6 @@ class TtsController {
e: 'Language not supported by TTS engine',
data: {
'targetLanguage': targetLanguage,
'availableLangCodes': _availableLangCodes,
},
);
if (eventID != null) {
@ -219,7 +230,13 @@ class TtsController {
}
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
'text': text,
},
);
}
}

@ -39,7 +39,14 @@ class ConversationBotSettingsState extends State<ConversationBotSettings> {
);
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack);
ErrorHandler.logError(
e: err,
s: stack,
data: {
"botOptions": botOptions.toJson(),
"roomID": widget.room.id,
},
);
}
}

@ -73,6 +73,9 @@ class PangeaRichTextState extends State<PangeaRichText> {
e: PangeaWarningError(error),
s: stackTrace,
m: "Error setting text span in PangeaRichText",
data: {
"newTextSpan": newTextSpan,
},
);
}
}
@ -103,6 +106,9 @@ class PangeaRichTextState extends State<PangeaRichText> {
e: PangeaWarningError(error),
s: stackTrace,
m: "Error fetching representation",
data: {
"langCode": widget.pangeaMessageEvent.messageDisplayLangCode,
},
);
return null;
}).then((event) {

@ -111,7 +111,13 @@ class SpanCardState extends State<SpanCard> {
}
} catch (e, s) {
// debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"matchIndex": widget.scm.matchIndex,
},
);
if (mounted) {
setState(() {
error = e;
@ -377,7 +383,11 @@ class WordMatchContent extends StatelessWidget {
);
} on Exception catch (e) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: e, s: StackTrace.current);
ErrorHandler.logError(
e: e,
s: StackTrace.current,
data: {},
);
rethrow;
}
}

@ -113,7 +113,13 @@ class WordDataCardController extends State<WordDataCard> {
GoogleAnalytics.contextualRequest();
} catch (err, stack) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: stack, data: req?.toJson());
ErrorHandler.logError(
e: err,
s: stack,
data: {
"request": req?.toJson(),
},
);
definitionError = Exception("Error getting definition");
} finally {
if (mounted) setState(() => isLoadingContextualDefinition = false);
@ -172,7 +178,13 @@ class WordDataCardView extends StatelessWidget {
);
}
if (controller.activeL1 == null || controller.activeL2 == null) {
ErrorHandler.logError(m: "should not be here");
ErrorHandler.logError(
m: "should not be here",
data: {
"activeL1": controller.activeL1?.toJson(),
"activeL2": controller.activeL2?.toJson(),
},
);
return CardErrorWidget(
error: controller.noLanguages,
maxWidth: AppConfig.toolbarMinWidth,

@ -54,7 +54,14 @@ class WordAudioButtonState extends State<WordAudioButton> {
widget.eventID,
);
} catch (e, s) {
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"text": widget.text,
"eventID": widget.eventID,
},
);
} finally {
if (mounted) {
setState(() => _isPlaying = false);

@ -108,7 +108,11 @@ Future<void> pLanguageDialog(
Navigator.pop(context);
} catch (err, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {},
);
rethrow;
} finally {
callback();

@ -57,6 +57,10 @@ class PSettingsSwitchListTileState
e: err,
m: "Failed to updates user setting",
s: s,
data: {
"newValue": newValue,
"currentValue": currentValue,
},
);
}
}

@ -149,7 +149,13 @@ class BackgroundPush {
: '/rooms/$roomId',
);
} catch (err, s) {
ErrorHandler.logError(e: err, s: s);
ErrorHandler.logError(
e: err,
s: s,
data: {
"roomId": message.data['room_id'],
},
);
}
}
// Pangea#
@ -226,6 +232,7 @@ class BackgroundPush {
ErrorHandler.logError(
e: "Error requesting notifications permission: $err",
s: s,
data: {},
);
}
// Pangea#
@ -316,7 +323,11 @@ class BackgroundPush {
} catch (e, s) {
Logs().e('[Push] Unable to set pushers', e, s);
// #Pangea
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {},
);
// Pangea#
}
}
@ -428,7 +439,13 @@ class BackgroundPush {
} catch (e, s) {
Logs().e('[Push] Failed to open room', e, s);
// #Pangea
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(
e: e,
s: s,
data: {
"roomID": response?.payload,
},
);
// Pangea#
}
}

@ -29,6 +29,7 @@ class ErrorReporter {
e: error,
s: stackTrace,
m: message ?? 'Error caught',
data: {},
);
}
}

@ -26,6 +26,7 @@ Future<DatabaseApi> flutterMatrixSdkDatabaseBuilder(Client client) async {
ErrorHandler.logError(
e: e,
s: s,
data: {"clientID": client.id},
m: "Failed to open matrix sdk database. Openning fallback database.",
);
// Pangea#
@ -37,6 +38,7 @@ Future<DatabaseApi> flutterMatrixSdkDatabaseBuilder(Client client) async {
ErrorHandler.logError(
e: e,
s: s,
data: {},
m: "Failed to delete matrix database after failed construction.",
);
}

@ -175,7 +175,7 @@ Future<void> _tryPushHelper(
} catch (e, s) {
Logs().e('Unable to get avatar picture', e, s);
// #Pangea
ErrorHandler.logError(e: e, s: s);
ErrorHandler.logError(e: e, s: s, data: {"avatarUri": avatar.toString()});
// Pangea#
}
try {

Loading…
Cancel
Save