Dio Integration
Learn more about the Sentry Dio integration for the Flutter SDK.
References to "transactions" on this page apply to the default transaction mode. In stream mode, this integration creates service spans instead, and Sentry sends them as they finish. See Streamed Spans for more information.
The sentry_dio library provides Dio support for Sentry using the HttpClientAdapter. It is able to collect breadcrumbs, run tracing for HTTP requests, and capture events for failed requests.
To add the Dio integration, add the sentry_dio dependency.
pubspec.yamldependencies:
sentry: ^9.26.0
sentry_dio: ^9.26.0
dio: ^4.0.0
dependencies:
sentry: ^9.26.0
sentry_dio: ^9.26.0
dio: ^4.0.0
Configuration should happen as early as possible in your application's lifecycle.
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry/sentry.dart';
Future<void> main() async {
await Sentry.init(
(options) {
options.dsn = '___PUBLIC_DSN___';
},
appRunner: initApp, // Init your App.
);
}
final dio = Dio();
// This *must* be the last initialization step of the Dio setup.
dio.addSentry(...);
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry/sentry.dart';
Future<void> main() async {
await Sentry.init(
(options) {
options.dsn = '___PUBLIC_DSN___';
},
appRunner: initApp, // Init your App.
);
}
final dio = Dio();
// This *must* be the last initialization step of the Dio setup.
dio.addSentry(...);
The Interceptors can also catch exceptions that may occur during requests — for example DioError.
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry();
final response = await dio.get<String>('https://wrong-url.dev/');
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry();
final response = await dio.get<String>('https://wrong-url.dev/');
This is an opt-out feature. The following example shows how to disable it:
await Sentry.init((options) {
options.captureFailedRequests = false;
});
await Sentry.init((options) {
options.captureFailedRequests = false;
});
You can customize which status codes should be considered failed requests by setting the failedRequestStatusCodes option when calling addSentry().
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry(
failedRequestStatusCodes: [
SentryStatusCode.range(400, 404), // Capture 400-404
SentryStatusCode(500), // Capture 500
],
);
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry(
failedRequestStatusCodes: [
SentryStatusCode.range(400, 404), // Capture 400-404
SentryStatusCode(500), // Capture 500
],
);
Default Behavior:
By default, failedRequestStatusCodes is set to [SentryStatusCode.range(500, 599)], which captures server errors (status codes 500-599).
To control which URLs should have failed requests captured, use the failedRequestTargets option. This is useful when you only want to capture errors from specific APIs or domains.
The SDK will only capture HTTP client errors if the request URL matches one of the provided targets. Targets can be:
- Strings that appear anywhere in the URL
- Regular expression patterns
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
// Capture failed requests only from specific domains
dio.addSentry(
failedRequestTargets: [
'api.example.com', // Matches any URL containing this string
'myapi.com', // Another domain to track
],
);
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
// Capture failed requests only from specific domains
dio.addSentry(
failedRequestTargets: [
'api.example.com', // Matches any URL containing this string
'myapi.com', // Another domain to track
],
);
Default Behavior:
By default, failedRequestTargets is set to ['.*'], which matches all URLs. This means all failed requests are captured (subject to failedRequestStatusCodes).
The Dio integration also provides insight into tracing for your HTTP requests done with Dio.
- The created spans attach to the active span. In transaction mode, that's the transaction bound to the scope; in stream mode, it's the span started with
Sentry.startSpan(). If no span is active, the span won't be sent to Sentry. - The SDK sets the span operation to
http.clientand the description to request$METHOD $url. For example,GET https://sentry.io. - The span finishes once the request has been executed.
- The span status depends on either the HTTP response code or
SpanStatus.internalError()if the code does not match any of Sentry's SpanStatus options. - When the HTTP request throws an Exception, Sentry's SDK associates this exception to the running span. If you haven't set the SDK to swallow the exception and capture it, the span and
SentryEventwill be linked when viewing it on the Issue Details page in sentry.io.
Before starting, ensure:
Call addSentry() on your instance of `Dio:
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry();
import 'package:sentry_dio/sentry_dio.dart';
final dio = Dio();
dio.addSentry();
import 'package:sentry_dio/sentry_dio.dart';
Future<void> makeWebRequestWithDio() async {
final dio = Dio();
dio.addSentry();
// If there is no active transaction, start one
final transaction = Sentry.startTransaction(
'dio-web-request',
'request',
bindToScope: true,
);
final span = transaction.startChild(
'dio',
description: 'desc',
);
Response<String>? response;
try {
response = await dio.get<String>(exampleUrl);
span.status = const SpanStatus.ok();
} catch (exception, stackTrace) {
span.throwable = exception;
span.status = const SpanStatus.internalError();
await Sentry.captureException(exception, stackTrace: stackTrace);
} finally {
await span.finish();
}
}
import 'package:sentry_dio/sentry_dio.dart';
Future<void> makeWebRequestWithDio() async {
final dio = Dio();
dio.addSentry();
// If there is no active transaction, start one
final transaction = Sentry.startTransaction(
'dio-web-request',
'request',
bindToScope: true,
);
final span = transaction.startChild(
'dio',
description: 'desc',
);
Response<String>? response;
try {
response = await dio.get<String>(exampleUrl);
span.status = const SpanStatus.ok();
} catch (exception, stackTrace) {
span.throwable = exception;
span.status = const SpanStatus.internalError();
await Sentry.captureException(exception, stackTrace: stackTrace);
} finally {
await span.finish();
}
}
import 'package:sentry_dio/sentry_dio.dart';
Future<void> makeWebRequestWithDio() async {
final dio = Dio();
dio.addSentry();
// Start a root span — the Dio integration attaches a span for the request
await Sentry.startSpan('dio-web-request', (span) async {
try {
final response = await dio.get<String>(exampleUrl);
} catch (exception, stackTrace) {
await Sentry.captureException(exception, stackTrace: stackTrace);
}
}, parentSpan: null);
}
To view the recorded transaction, log into sentry.io and open your project. Clicking Performance will open a page with transactions, where you can select the just recorded transaction with the name dio-web-request.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").