Error and crash reporting

  • Latest Dynatrace
  • Explanation
  • 1-min read
  • Published Dec 24, 2025

Dynatrace provides comprehensive error and crash reporting for Flutter applications. The plugin automatically captures unhandled exceptions, Flutter framework errors, and platform-level crashes. You can also manually report errors and exceptions with additional context.

Automatic crash reporting

When you initialize the Dynatrace Flutter plugin using Dynatrace().start(), automatic crash reporting is enabled by default. The plugin captures errors from multiple sources to ensure comprehensive coverage.

How it works

The plugin registers error handlers at two levels:

  • FlutterError.onError—captures Flutter framework errors from rendering, layout, and widget lifecycle, as well as errors from user interactions.
  • PlatformDispatcher.instance.onError—captures low-level platform errors and unhandled asynchronous exceptions that escape all error zones.

Disable automatic crash reporting

Automatic crash reporting is enabled by default. If you prefer to handle error reporting manually, you can disable it in the configuration. To disable automatic crash reporting, set crashReporting to false in your dynatrace.config.yaml:

Android:

android:
config:
"dynatrace {
configurations {
defaultConfig {
crashReporting false
}
}
}"

iOS:

ios:
config:
"<key>DTXCrashReportingEnabled</key>
<false/>"

Or in case of manual startup:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
void main() {
Dynatrace().start(
MyApp(),
configuration: Configuration(
beaconUrl: 'BeaconUrl',
applicationId: 'AppId',
reportCrash: false),
);
}

Capture errors from isolates

Dart isolates run independently with their own memory and event loop. Errors in isolates do not automatically propagate to the main isolate. To capture these errors, you must set up error listeners.

Use Isolate.spawn with error listener

The recommended approach is to pass a DynatraceIsolateErrorReceivePort when spawning isolates:

import 'dart:isolate';
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
Future<void> runBackgroundTask() async {
await Isolate.spawn(
(message) {
// Background work that might throw
throw Exception('Error in background task');
},
null,
onError: DynatraceIsolateErrorReceivePort().sendPort,
);
}

Add error listener to existing isolate

For isolates that are already created, use the extension method:

import 'dart:isolate';
import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
Future<void> runIsolate() async {
final receivePort = ReceivePort();
final isolate = await Isolate.spawn(
heavyComputation,
receivePort.sendPort,
);
// Add Dynatrace error listener
isolate.addDynatraceErrorListener();
receivePort.listen((data) {
print('Received: $data');
});
}
void heavyComputation(SendPort sendPort) {
// This error will be captured by Dynatrace
throw Exception('Error in isolate computation');
}

Errors that occur before the error listener is attached will not be captured. For best results, pass the error port directly to Isolate.spawn using the onError parameter.

ANR reporting

Application Not Responding (ANR) errors occur when the main thread is blocked for too long. Dynatrace automatically captures ANR events.

What is captured

ANR events indicate that your app's UI became unresponsive, causing user frustration.

Configuration

ANR reporting is enabled by default. To disable it:

Android:

android:
config:
"dynatrace {
configurations {
defaultConfig {
anrReporting false
}
}
}"

iOS:

ios:
config:
"<key>DTXANRReportingEnabled</key>
<false/>"

ANR events are only sent if the user restarts the app within 10 minutes of the ANR occurring. On Android, ANR reporting requires Android 11 or higher.

Manual error reporting

For errors that you handle in your code but still want to report to Dynatrace, use the manual reporting APIs.

sendExceptionEvent

Use sendExceptionEvent() to report exceptions with full context and custom properties:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
try {
await riskyOperation();
} catch (exception, stackTrace) {
// Report with stack trace
Dynatrace().sendExceptionEvent(
ExceptionEventData(exception, stackTrace: stackTrace),
);
}

Add custom properties

Add context to help with debugging:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';
try {
await fetchUserData(userId);
} catch (exception, stackTrace) {
Dynatrace().sendExceptionEvent(
ExceptionEventData(
exception,
stackTrace: stackTrace,
eventProperties: {
'event_properties.operation': 'fetch_user_data',
'event_properties.user_id_hash': userId.hashCode,
'event_properties.retry_count': retryCount,
},
),
);
}
Related tags
Digital Experience