Skip to content

Commit

Permalink
feat: #30 add innerError to sendCustom method (#195)
Browse files Browse the repository at this point in the history
* feat: #30 add innerError to sendCustom method

* update readme

* remove TODO
  • Loading branch information
miquelbeltran authored Aug 27, 2024
1 parent bb507b5 commit 9901ea0
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ All arguments but `error` are optional. This method is mainly a convenience wrap

Call `Raygun.sendCustom(className, reason, tags, customData, stackTrace)` to send custom errors to Raygun with your own customised `className` and `reason`. As with `.sendException()`, `tags`, `customData` and `stackTrace` are optional.

You can also provide an optional `innerError` `Exception` object that will be attached to the error report.

For example:

```dart
Expand All @@ -154,6 +156,7 @@ Raygun.sendCustom(
'custom2': 42,
},
stackTrace: StackTrace.current,
innerError: Exception('Error!'),
);
```

Expand Down
14 changes: 13 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,10 @@ class _MyAppState extends State<MyApp> {
'custom2': 42,
},
stackTrace: StackTrace.current,
innerError: const MyCustomException('Custom exception'),
);
},
child: const Text('Send custom error with tags and customData'),
child: const Text('Send custom error with all options'),
),

// example: Button tap adds breadcrumb to future error message
Expand Down Expand Up @@ -199,3 +200,14 @@ class _MyAppState extends State<MyApp> {
);
}
}

class MyCustomException implements Exception {
const MyCustomException(this.message);

final String message;

@override
String toString() {
return 'MyCustomException: $message';
}
}
13 changes: 12 additions & 1 deletion lib/raygun4flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,16 @@ class Raygun {
///
/// [stackTrace] optional parameter, if not provided this method will obtain
/// the current stacktrace automatically.
///
/// [innerError] optional [Exception] to attach as "innerError"
/// in the error report.
static Future<void> sendCustom({
required String className,
required String reason,
List<String>? tags,
Map<String, dynamic>? customData,
StackTrace? stackTrace,
Exception? innerError,
}) async {
Trace trace;
if (stackTrace == null) {
Expand All @@ -109,7 +113,14 @@ class Raygun {
trace = Trace.from(stackTrace);
}

return CrashReporting.send(className, reason, tags, customData, trace);
return CrashReporting.send(
className,
reason,
tags,
customData,
trace,
innerError,
);
}

/// Sets a List of tags which will be sent along with every exception.
Expand Down
8 changes: 7 additions & 1 deletion lib/src/messages/raygun_error_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class RaygunErrorMessage {
String message;
String className;

// todo: innerError is null at the moment
RaygunErrorMessage? innerError;

List<RaygunErrorStackTraceLineMessage> stackTrace = [];
Expand All @@ -33,6 +32,13 @@ class RaygunErrorMessage {
.toList();
}

factory RaygunErrorMessage.fromException(Exception exception) {
return RaygunErrorMessage(
exception.runtimeType.toString(),
exception.toString(),
);
}

factory RaygunErrorMessage.fromJson(
Map<String, dynamic> json,
) =>
Expand Down
13 changes: 12 additions & 1 deletion lib/src/raygun_crash_reporting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ class CrashReporting {
List<String>? tags,
Map? customData,
Trace? trace,
Exception? innerError,
) async {
final RaygunMessage msg = await _buildMessage(className, reason, trace);
final RaygunMessage msg = await _buildMessage(
className,
reason,
trace,
innerError,
);

msg.details.tags = tags ?? [];
final globalTags = Settings.tags;
Expand Down Expand Up @@ -70,13 +76,18 @@ Future<RaygunMessage> _buildMessage(
String className,
String reason,
Trace? trace,
Exception? innerError,
) async {
final raygunMessage = RaygunMessage();

raygunMessage.details.error = RaygunErrorMessage(className, reason);
if (trace != null) {
raygunMessage.details.error!.setStackTrace(trace);
}
if (innerError != null) {
raygunMessage.details.error!.innerError =
RaygunErrorMessage.fromException(innerError);
}

raygunMessage.details.client = RaygunClientMessage();
raygunMessage.details.breadcrumbs.addAll(Settings.breadcrumbs);
Expand Down
18 changes: 18 additions & 0 deletions test/raygun4flutter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,24 @@ void main() {
expect(capturedBody['details']['userCustomData'], {'custom': 42});
});

test('sendCustom with innerError', () async {
await Raygun.sendCustom(
className: 'CLASSNAME',
reason: 'REASON',
innerError: Exception('MESSAGE'),
);

// main error should be custom className and reason
expect(capturedBody['details']['error']['message'], 'REASON');
expect(capturedBody['details']['error']['className'], 'CLASSNAME');

// innerError should be exception message and type
expect(capturedBody['details']['error']['innerError']['message'],
'Exception: MESSAGE');
expect(capturedBody['details']['error']['innerError']['className'],
'_Exception');
});

test('Breadcrumb', () async {
Raygun.recordBreadcrumb('BREADCRUMB');
final breadcrumbMessage = RaygunBreadcrumbMessage(
Expand Down

0 comments on commit 9901ea0

Please sign in to comment.