feat(cronet_http): decode cronet exceptions (#1912)
diff --git a/pkgs/cronet_http/CHANGELOG.md b/pkgs/cronet_http/CHANGELOG.md
index 037f315..fb40782 100644
--- a/pkgs/cronet_http/CHANGELOG.md
+++ b/pkgs/cronet_http/CHANGELOG.md
@@ -1,6 +1,7 @@
 ## 1.9.0-wip
 
 * Add `CronetEngine.startNetLogToFile` and `CronetEngine.stopNetLog`.
+* Decode Java `CronetException` into Dart equivalents.
 
 ## 1.8.0
 
diff --git a/pkgs/cronet_http/example/integration_test/client_profile_test.dart b/pkgs/cronet_http/example/integration_test/client_profile_test.dart
index 8cb4f7d..ca43bb7 100644
--- a/pkgs/cronet_http/example/integration_test/client_profile_test.dart
+++ b/pkgs/cronet_http/example/integration_test/client_profile_test.dart
@@ -117,7 +117,8 @@
         expect(profile.requestData.bodyBytes, 'Hi'.codeUnits);
         expect(profile.requestData.contentLength, 2);
         expect(profile.requestData.endTime, isNotNull);
-        expect(profile.requestData.error, startsWith('ClientException:'));
+        expect(
+            profile.requestData.error, startsWith('NetworkClientException:'));
         expect(
             profile.requestData.headers, containsPair('Content-Length', ['2']));
         expect(profile.requestData.headers,
@@ -200,7 +201,8 @@
         expect(profile.responseData.compressionState, isNull);
         expect(profile.responseData.contentLength, 11);
         expect(profile.responseData.endTime, isNotNull);
-        expect(profile.responseData.error, startsWith('ClientException:'));
+        expect(
+            profile.responseData.error, startsWith('NetworkClientException:'));
         expect(profile.responseData.headers,
             containsPair('content-type', ['text/plain']));
         expect(profile.responseData.headers,
diff --git a/pkgs/cronet_http/example/integration_test/client_test.dart b/pkgs/cronet_http/example/integration_test/client_test.dart
index aa7fd93..3b3be5e 100644
--- a/pkgs/cronet_http/example/integration_test/client_test.dart
+++ b/pkgs/cronet_http/example/integration_test/client_test.dart
@@ -115,9 +115,68 @@
   });
 }
 
+Future<void> testCronetExceptions() async {
+  test('NetworkClientException', () async {
+    final server = (await ServerSocket.bind('localhost', 0))
+      ..listen((socket) async {
+        socket.write('Gibberish');
+        await socket.close();
+      });
+    addTearDown(server.close);
+    final client = CronetClient.defaultCronetEngine();
+    expect(
+      client.send(Request('GET', Uri.http('localhost:${server.port}'))),
+      throwsA(isA<NetworkException>()
+          .having((e) => e.errorCode, 'errorCode', 11 // ERROR_OTHER
+              )
+          .having((e) => e.cronetInternalErrorCode, 'cronetInternalErrorCode',
+              -370 // INVALID_HTTP_RESPONSE
+              )
+          .having((e) => e.toString(), 'toString',
+              startsWith('NetworkClientException:'))),
+    );
+  });
+
+  test('QuicException', () async {
+    final udpSocket =
+        await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, 0);
+    addTearDown(udpSocket.close);
+
+    udpSocket.listen((event) {
+      if (event == RawSocketEvent.read) {
+        final datagram = udpSocket.receive();
+        if (datagram != null) {
+          udpSocket
+              .send([0x01, 0x02, 0x03, 0x04], datagram.address, datagram.port);
+        }
+      }
+    });
+
+    final port = udpSocket.port;
+
+    final engine = CronetEngine.build(enableQuic: true, quicHints: [
+      ('127.0.0.1', port, port),
+    ]);
+    final client = CronetClient.fromCronetEngine(engine);
+
+    expect(
+      client.send(Request('GET', Uri.parse('https://127.0.0.1:$port'))),
+      throwsA(isA<QuicException>()
+          .having(
+              (e) => e.errorCode, 'errorCode', 10 // ERROR_QUIC_PROTOCOL_FAILED
+              )
+          .having(
+              (e) => e.quicDetailedErrorCode, 'quicDetailedErrorCode', isNot(0))
+          .having(
+              (e) => e.toString(), 'toString', startsWith('QuicException:'))),
+    );
+  });
+}
+
 void main() async {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
 
   await testConformance();
   await testCronetStreamedResponse();
+  await testCronetExceptions();
 }
diff --git a/pkgs/cronet_http/example/integration_test/cronet_engine_test.dart b/pkgs/cronet_http/example/integration_test/cronet_engine_test.dart
index 2c07e18..b3e9dc4 100644
--- a/pkgs/cronet_http/example/integration_test/cronet_engine_test.dart
+++ b/pkgs/cronet_http/example/integration_test/cronet_engine_test.dart
@@ -123,21 +123,6 @@
 
 void testQuicHints() {
   group('quicHints', () {
-    late HttpServer server;
-
-    setUp(() async {
-      server = (await HttpServer.bind('localhost', 0))
-        ..listen((request) async {
-          await request.drain<void>();
-          request.response.headers.set('Content-Type', 'text/plain');
-          request.response.write('Hello World');
-          await request.response.close();
-        });
-    });
-    tearDown(() {
-      server.close();
-    });
-
     test('quic hints', () async {
       final engine = CronetEngine.build(
           cacheMode: CacheMode.diskNoHttp,
diff --git a/pkgs/cronet_http/jnigen.yaml b/pkgs/cronet_http/jnigen.yaml
index 2413c9f..b78ec2d 100644
--- a/pkgs/cronet_http/jnigen.yaml
+++ b/pkgs/cronet_http/jnigen.yaml
@@ -11,10 +11,16 @@
 
 classes:
   - 'io.flutter.plugins.cronet_http.UrlRequestCallbackProxy'
+  - 'java.io.IOException'
+  - 'java.lang.Exception'
+  - 'java.lang.Throwable'
   - 'java.net.URL'
   - 'java.util.concurrent.Executors'
   - 'org.chromium.net.CronetEngine'
+  - 'org.chromium.net.CallbackException'
   - 'org.chromium.net.CronetException'
+  - 'org.chromium.net.NetworkException'
+  - 'org.chromium.net.QuicException'
   - 'org.chromium.net.UploadDataProviders'
   - 'org.chromium.net.UrlRequest'
   - 'org.chromium.net.UrlResponseInfo'
diff --git a/pkgs/cronet_http/lib/src/cronet_client.dart b/pkgs/cronet_http/lib/src/cronet_client.dart
index d579eec..26cc019 100644
--- a/pkgs/cronet_http/lib/src/cronet_client.dart
+++ b/pkgs/cronet_http/lib/src/cronet_client.dart
@@ -13,6 +13,127 @@
 final _digitRegex = RegExp(r'^\d+$');
 const _bufferSize = 10 * 1024; // The size of the Cronet read buffer.
 
+/// A [ClientException] generated from a Java [`CronetException`][1].
+///
+/// [1]: https://developer.android.com/develop/connectivity/cronet/reference/org/chromium/net/CronetException.html
+class CronetException extends ClientException {
+  CronetException(super.message, Uri super.uri);
+
+  @override
+  String toString() => 'CronetClientException: $message, uri=$uri';
+}
+
+/// A [ClientException] generated from a Java [`CallbackException`][1].
+///
+/// [1]: https://developer.android.com/develop/connectivity/cronet/reference/org/chromium/net/CallbackException.html
+class CallbackException extends CronetException {
+  CallbackException._(super.message, super.uri);
+
+  @override
+  String toString() => 'CallbackException: $message, uri=$uri';
+}
+
+/// A [ClientException] generated from a Java [`NetworkException`][1].
+///
+/// [1]: https://developer.android.com/develop/connectivity/cronet/reference/org/chromium/net/NetworkException.html
+class NetworkException extends CronetException {
+  /// The Cronet internal error code.
+  ///
+  /// This may provide more specific error diagnosis than [errorCode].
+  ///
+  /// The list of possible value is contained in [net_error_list.h][1].
+  ///
+  /// [1]: https://chromium.googlesource.com/chromium/src/+/main/net/base/net_error_list.h
+  final int cronetInternalErrorCode;
+
+  /// The error code associated with the failure, which is one of the `ERROR_*`
+  /// constants defined in [`NetworkException`][1].
+  ///
+  /// For example, a value of `6` corresponds to `ERROR_CONNECTION_TIMED_OUT`.
+  ///
+  /// [1]: https://developer.android.com/develop/connectivity/cronet/reference/org/chromium/net/NetworkException.html#constants
+  final int errorCode;
+
+  /// Whether retrying this request right away might succeed.
+  ///
+  /// For example, this is `true` when [errorCode] is `ERROR_NETWORK_CHANGED`
+  /// because trying the request might succeed using the new network
+  /// configuration.
+  final bool immediatelyRetryable;
+
+  NetworkException._(super.message, super.uri,
+      {required this.cronetInternalErrorCode,
+      required this.errorCode,
+      required this.immediatelyRetryable});
+
+  @override
+  String toString() => 'NetworkClientException: $message, uri=$uri, '
+      'errorCode=$errorCode, cronetInternalErrorCode=$cronetInternalErrorCode, '
+      'immediatelyRetryable=$immediatelyRetryable';
+}
+
+/// A [ClientException] generated from a Java [`QuicException`][1].
+///
+/// [1]: https://developer.android.com/develop/connectivity/cronet/reference/org/chromium/net/QuicException.html
+class QuicException extends NetworkException {
+  /// The QUIC error code, which is a value from [`QuicErrorCode`][1].
+  ///
+  /// [1]: https://source.chromium.org/chromium/chromium/src/+/main:net/third_party/quiche/src/quiche/quic/core/quic_error_codes.h
+  final int quicDetailedErrorCode;
+
+  QuicException._(
+    super.message,
+    super.uri, {
+    required this.quicDetailedErrorCode,
+    required super.errorCode,
+    required super.cronetInternalErrorCode,
+    required super.immediatelyRetryable,
+  }) : super._();
+
+  @override
+  String toString() => 'QuicException: $message, uri=$uri, '
+      'errorCode=$errorCode, cronetInternalErrorCode=$cronetInternalErrorCode, '
+      'immediatelyRetryable=$immediatelyRetryable, '
+      'quicDetailedErrorCode=$quicDetailedErrorCode';
+}
+
+ClientException _convertCronetException(jb.CronetException? e, Uri uri) {
+  if (e == null) {
+    return CronetException('unknown exception', uri);
+  }
+  final message = e.getMessage()?.toDartString(releaseOriginal: true) ??
+      'unknown exception';
+
+  if (e.isA(jb.QuicException.type)) {
+    final quicException = e.as(jb.QuicException.type, releaseOriginal: true);
+    return QuicException._(
+      message,
+      uri,
+      quicDetailedErrorCode: quicException.getQuicDetailedErrorCode(),
+      errorCode: quicException.getErrorCode(),
+      cronetInternalErrorCode: quicException.getCronetInternalErrorCode(),
+      immediatelyRetryable: quicException.immediatelyRetryable(),
+    );
+  }
+  if (e.isA(jb.NetworkException.type)) {
+    final networkException =
+        e.as(jb.NetworkException.type, releaseOriginal: true);
+    return NetworkException._(
+      message,
+      uri,
+      cronetInternalErrorCode: networkException.getCronetInternalErrorCode(),
+      errorCode: networkException.getErrorCode(),
+      immediatelyRetryable: networkException.immediatelyRetryable(),
+    );
+  }
+
+  if (e.isA(jb.CallbackException.type)) {
+    return CallbackException._(message, uri);
+  }
+
+  return CronetException(message, uri);
+}
+
 /// This class can be removed when `package:http` v2 is released.
 class _StreamedResponseWithUrl extends StreamedResponse
     implements BaseResponseWithUrl {
@@ -430,8 +551,8 @@
         cronetException?.releasedBy(arena);
         if (responseStreamCancelled) return;
         responseStreamCancelled = true;
-        final error = ClientException(
-            'Cronet exception: ${cronetException.toString()}', request.url);
+        final error = _convertCronetException(cronetException, request.url);
+
         if (responseStream == null) {
           responseCompleter.completeError(error);
         } else {
diff --git a/pkgs/cronet_http/lib/src/jni/jni_bindings.dart b/pkgs/cronet_http/lib/src/jni/jni_bindings.dart
index c03a8b8..af70cc1 100644
--- a/pkgs/cronet_http/lib/src/jni/jni_bindings.dart
+++ b/pkgs/cronet_http/lib/src/jni/jni_bindings.dart
@@ -1048,6 +1048,958 @@
   }
 }
 
+/// from: `java.io.IOException`
+class IOException extends Exception {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<IOException> $type;
+
+  @jni$_.internal
+  IOException.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class = jni$_.JClass.forName(r'java/io/IOException');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<IOException?> nullableType =
+      $IOException$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<IOException> type = $IOException$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'()V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void <init>()`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory IOException() {
+    return IOException.fromReference(
+        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
+            .reference);
+  }
+
+  static final _id_new1 = _class.constructorId(
+    r'(Ljava/lang/String;)V',
+  );
+
+  static final _new1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory IOException.new1(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return IOException.fromReference(_new1(_class.reference.pointer,
+            _id_new1 as jni$_.JMethodIDPtr, _$string.pointer)
+        .reference);
+  }
+
+  static final _id_new2 = _class.constructorId(
+    r'(Ljava/lang/String;Ljava/lang/Throwable;)V',
+  );
+
+  static final _new2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string, java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory IOException.new2(
+    jni$_.JString? string,
+    Throwable? throwable,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return IOException.fromReference(_new2(
+            _class.reference.pointer,
+            _id_new2 as jni$_.JMethodIDPtr,
+            _$string.pointer,
+            _$throwable.pointer)
+        .reference);
+  }
+
+  static final _id_new3 = _class.constructorId(
+    r'(Ljava/lang/Throwable;)V',
+  );
+
+  static final _new3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory IOException.new3(
+    Throwable? throwable,
+  ) {
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return IOException.fromReference(_new3(_class.reference.pointer,
+            _id_new3 as jni$_.JMethodIDPtr, _$throwable.pointer)
+        .reference);
+  }
+}
+
+final class $IOException$NullableType$ extends jni$_.JType<IOException?> {
+  @jni$_.internal
+  const $IOException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/io/IOException;';
+
+  @jni$_.internal
+  @core$_.override
+  IOException? fromReference(jni$_.JReference reference) => reference.isNull
+      ? null
+      : IOException.fromReference(
+          reference,
+        );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $Exception$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<IOException?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 3;
+
+  @core$_.override
+  int get hashCode => ($IOException$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($IOException$NullableType$) &&
+        other is $IOException$NullableType$;
+  }
+}
+
+final class $IOException$Type$ extends jni$_.JType<IOException> {
+  @jni$_.internal
+  const $IOException$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/io/IOException;';
+
+  @jni$_.internal
+  @core$_.override
+  IOException fromReference(jni$_.JReference reference) =>
+      IOException.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $Exception$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<IOException?> get nullableType =>
+      const $IOException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 3;
+
+  @core$_.override
+  int get hashCode => ($IOException$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($IOException$Type$) &&
+        other is $IOException$Type$;
+  }
+}
+
+/// from: `java.lang.Exception`
+class Exception extends Throwable {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<Exception> $type;
+
+  @jni$_.internal
+  Exception.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class = jni$_.JClass.forName(r'java/lang/Exception');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<Exception?> nullableType =
+      $Exception$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<Exception> type = $Exception$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'()V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void <init>()`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Exception() {
+    return Exception.fromReference(
+        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
+            .reference);
+  }
+
+  static final _id_new1 = _class.constructorId(
+    r'(Ljava/lang/String;)V',
+  );
+
+  static final _new1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Exception.new1(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return Exception.fromReference(_new1(_class.reference.pointer,
+            _id_new1 as jni$_.JMethodIDPtr, _$string.pointer)
+        .reference);
+  }
+
+  static final _id_new2 = _class.constructorId(
+    r'(Ljava/lang/String;Ljava/lang/Throwable;)V',
+  );
+
+  static final _new2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string, java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Exception.new2(
+    jni$_.JString? string,
+    Throwable? throwable,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return Exception.fromReference(_new2(
+            _class.reference.pointer,
+            _id_new2 as jni$_.JMethodIDPtr,
+            _$string.pointer,
+            _$throwable.pointer)
+        .reference);
+  }
+
+  static final _id_new3 = _class.constructorId(
+    r'(Ljava/lang/Throwable;)V',
+  );
+
+  static final _new3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Exception.new3(
+    Throwable? throwable,
+  ) {
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return Exception.fromReference(_new3(_class.reference.pointer,
+            _id_new3 as jni$_.JMethodIDPtr, _$throwable.pointer)
+        .reference);
+  }
+}
+
+final class $Exception$NullableType$ extends jni$_.JType<Exception?> {
+  @jni$_.internal
+  const $Exception$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/lang/Exception;';
+
+  @jni$_.internal
+  @core$_.override
+  Exception? fromReference(jni$_.JReference reference) => reference.isNull
+      ? null
+      : Exception.fromReference(
+          reference,
+        );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $Throwable$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<Exception?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 2;
+
+  @core$_.override
+  int get hashCode => ($Exception$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($Exception$NullableType$) &&
+        other is $Exception$NullableType$;
+  }
+}
+
+final class $Exception$Type$ extends jni$_.JType<Exception> {
+  @jni$_.internal
+  const $Exception$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/lang/Exception;';
+
+  @jni$_.internal
+  @core$_.override
+  Exception fromReference(jni$_.JReference reference) =>
+      Exception.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $Throwable$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<Exception?> get nullableType => const $Exception$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 2;
+
+  @core$_.override
+  int get hashCode => ($Exception$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($Exception$Type$) && other is $Exception$Type$;
+  }
+}
+
+/// from: `java.lang.Throwable`
+class Throwable extends jni$_.JObject {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<Throwable> $type;
+
+  @jni$_.internal
+  Throwable.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class = jni$_.JClass.forName(r'java/lang/Throwable');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<Throwable?> nullableType =
+      $Throwable$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<Throwable> type = $Throwable$Type$();
+  static final _id_new$ = _class.constructorId(
+    r'()V',
+  );
+
+  static final _new$ = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void <init>()`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Throwable() {
+    return Throwable.fromReference(
+        _new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr)
+            .reference);
+  }
+
+  static final _id_new$1 = _class.constructorId(
+    r'(Ljava/lang/String;)V',
+  );
+
+  static final _new$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Throwable.new$1(
+    jni$_.JString? string,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    return Throwable.fromReference(_new$1(_class.reference.pointer,
+            _id_new$1 as jni$_.JMethodIDPtr, _$string.pointer)
+        .reference);
+  }
+
+  static final _id_new$2 = _class.constructorId(
+    r'(Ljava/lang/String;Ljava/lang/Throwable;)V',
+  );
+
+  static final _new$2 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                  jni$_.Pointer<jni$_.Void>,
+                  jni$_.JMethodIDPtr,
+                  jni$_.VarArgs<
+                      (
+                        jni$_.Pointer<jni$_.Void>,
+                        jni$_.Pointer<jni$_.Void>
+                      )>)>>('globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr,
+              jni$_.Pointer<jni$_.Void>,
+              jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.String string, java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Throwable.new$2(
+    jni$_.JString? string,
+    Throwable? throwable,
+  ) {
+    final _$string = string?.reference ?? jni$_.jNullReference;
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return Throwable.fromReference(_new$2(
+            _class.reference.pointer,
+            _id_new$2 as jni$_.JMethodIDPtr,
+            _$string.pointer,
+            _$throwable.pointer)
+        .reference);
+  }
+
+  static final _id_new$3 = _class.constructorId(
+    r'(Ljava/lang/Throwable;)V',
+  );
+
+  static final _new$3 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_NewObject')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void <init>(java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  factory Throwable.new$3(
+    Throwable? throwable,
+  ) {
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return Throwable.fromReference(_new$3(_class.reference.pointer,
+            _id_new$3 as jni$_.JMethodIDPtr, _$throwable.pointer)
+        .reference);
+  }
+
+  static final _id_addSuppressed = _class.instanceMethodId(
+    r'addSuppressed',
+    r'(Ljava/lang/Throwable;)V',
+  );
+
+  static final _addSuppressed = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public final void addSuppressed(java.lang.Throwable throwable)`
+  void addSuppressed(
+    Throwable? throwable,
+  ) {
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    _addSuppressed(reference.pointer, _id_addSuppressed as jni$_.JMethodIDPtr,
+            _$throwable.pointer)
+        .check();
+  }
+
+  static final _id_fillInStackTrace = _class.instanceMethodId(
+    r'fillInStackTrace',
+    r'()Ljava/lang/Throwable;',
+  );
+
+  static final _fillInStackTrace = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.Throwable fillInStackTrace()`
+  /// The returned object must be released after use, by calling the [release] method.
+  Throwable? fillInStackTrace() {
+    return _fillInStackTrace(
+            reference.pointer, _id_fillInStackTrace as jni$_.JMethodIDPtr)
+        .object<Throwable?>(const $Throwable$NullableType$());
+  }
+
+  static final _id_getCause = _class.instanceMethodId(
+    r'getCause',
+    r'()Ljava/lang/Throwable;',
+  );
+
+  static final _getCause = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.Throwable getCause()`
+  /// The returned object must be released after use, by calling the [release] method.
+  Throwable? getCause() {
+    return _getCause(reference.pointer, _id_getCause as jni$_.JMethodIDPtr)
+        .object<Throwable?>(const $Throwable$NullableType$());
+  }
+
+  static final _id_getLocalizedMessage = _class.instanceMethodId(
+    r'getLocalizedMessage',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getLocalizedMessage = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String getLocalizedMessage()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getLocalizedMessage() {
+    return _getLocalizedMessage(
+            reference.pointer, _id_getLocalizedMessage as jni$_.JMethodIDPtr)
+        .object<jni$_.JString?>(const jni$_.$JString$NullableType$());
+  }
+
+  static final _id_getMessage = _class.instanceMethodId(
+    r'getMessage',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _getMessage = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String getMessage()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? getMessage() {
+    return _getMessage(reference.pointer, _id_getMessage as jni$_.JMethodIDPtr)
+        .object<jni$_.JString?>(const jni$_.$JString$NullableType$());
+  }
+
+  static final _id_getStackTrace = _class.instanceMethodId(
+    r'getStackTrace',
+    r'()[Ljava/lang/StackTraceElement;',
+  );
+
+  static final _getStackTrace = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.StackTraceElement[] getStackTrace()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<jni$_.JObject?>? getStackTrace() {
+    return _getStackTrace(
+            reference.pointer, _id_getStackTrace as jni$_.JMethodIDPtr)
+        .object<jni$_.JArray<jni$_.JObject?>?>(
+            const jni$_.$JArray$NullableType$<jni$_.JObject?>(
+                jni$_.$JObject$NullableType$()));
+  }
+
+  static final _id_getSuppressed = _class.instanceMethodId(
+    r'getSuppressed',
+    r'()[Ljava/lang/Throwable;',
+  );
+
+  static final _getSuppressed = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public final java.lang.Throwable[] getSuppressed()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JArray<Throwable?>? getSuppressed() {
+    return _getSuppressed(
+            reference.pointer, _id_getSuppressed as jni$_.JMethodIDPtr)
+        .object<jni$_.JArray<Throwable?>?>(
+            const jni$_.$JArray$NullableType$<Throwable?>(
+                $Throwable$NullableType$()));
+  }
+
+  static final _id_initCause = _class.instanceMethodId(
+    r'initCause',
+    r'(Ljava/lang/Throwable;)Ljava/lang/Throwable;',
+  );
+
+  static final _initCause = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public java.lang.Throwable initCause(java.lang.Throwable throwable)`
+  /// The returned object must be released after use, by calling the [release] method.
+  Throwable? initCause(
+    Throwable? throwable,
+  ) {
+    final _$throwable = throwable?.reference ?? jni$_.jNullReference;
+    return _initCause(reference.pointer, _id_initCause as jni$_.JMethodIDPtr,
+            _$throwable.pointer)
+        .object<Throwable?>(const $Throwable$NullableType$());
+  }
+
+  static final _id_printStackTrace = _class.instanceMethodId(
+    r'printStackTrace',
+    r'()V',
+  );
+
+  static final _printStackTrace = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JThrowablePtr Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public void printStackTrace()`
+  void printStackTrace() {
+    _printStackTrace(
+            reference.pointer, _id_printStackTrace as jni$_.JMethodIDPtr)
+        .check();
+  }
+
+  static final _id_printStackTrace$1 = _class.instanceMethodId(
+    r'printStackTrace',
+    r'(Ljava/io/PrintStream;)V',
+  );
+
+  static final _printStackTrace$1 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void printStackTrace(java.io.PrintStream printStream)`
+  void printStackTrace$1(
+    jni$_.JObject? printStream,
+  ) {
+    final _$printStream = printStream?.reference ?? jni$_.jNullReference;
+    _printStackTrace$1(reference.pointer,
+            _id_printStackTrace$1 as jni$_.JMethodIDPtr, _$printStream.pointer)
+        .check();
+  }
+
+  static final _id_printStackTrace$2 = _class.instanceMethodId(
+    r'printStackTrace',
+    r'(Ljava/io/PrintWriter;)V',
+  );
+
+  static final _printStackTrace$2 = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void printStackTrace(java.io.PrintWriter printWriter)`
+  void printStackTrace$2(
+    jni$_.JObject? printWriter,
+  ) {
+    final _$printWriter = printWriter?.reference ?? jni$_.jNullReference;
+    _printStackTrace$2(reference.pointer,
+            _id_printStackTrace$2 as jni$_.JMethodIDPtr, _$printWriter.pointer)
+        .check();
+  }
+
+  static final _id_setStackTrace = _class.instanceMethodId(
+    r'setStackTrace',
+    r'([Ljava/lang/StackTraceElement;)V',
+  );
+
+  static final _setStackTrace = jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JThrowablePtr Function(
+                      jni$_.Pointer<jni$_.Void>,
+                      jni$_.JMethodIDPtr,
+                      jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>)>>(
+          'globalEnv_CallVoidMethod')
+      .asFunction<
+          jni$_.JThrowablePtr Function(jni$_.Pointer<jni$_.Void>,
+              jni$_.JMethodIDPtr, jni$_.Pointer<jni$_.Void>)>();
+
+  /// from: `public void setStackTrace(java.lang.StackTraceElement[] stackTraceElements)`
+  void setStackTrace(
+    jni$_.JArray<jni$_.JObject?>? stackTraceElements,
+  ) {
+    final _$stackTraceElements =
+        stackTraceElements?.reference ?? jni$_.jNullReference;
+    _setStackTrace(reference.pointer, _id_setStackTrace as jni$_.JMethodIDPtr,
+            _$stackTraceElements.pointer)
+        .check();
+  }
+
+  static final _id_toString$1 = _class.instanceMethodId(
+    r'toString',
+    r'()Ljava/lang/String;',
+  );
+
+  static final _toString$1 = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallObjectMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public java.lang.String toString()`
+  /// The returned object must be released after use, by calling the [release] method.
+  jni$_.JString? toString$1() {
+    return _toString$1(reference.pointer, _id_toString$1 as jni$_.JMethodIDPtr)
+        .object<jni$_.JString?>(const jni$_.$JString$NullableType$());
+  }
+}
+
+final class $Throwable$NullableType$ extends jni$_.JType<Throwable?> {
+  @jni$_.internal
+  const $Throwable$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/lang/Throwable;';
+
+  @jni$_.internal
+  @core$_.override
+  Throwable? fromReference(jni$_.JReference reference) => reference.isNull
+      ? null
+      : Throwable.fromReference(
+          reference,
+        );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const jni$_.$JObject$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<Throwable?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 1;
+
+  @core$_.override
+  int get hashCode => ($Throwable$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($Throwable$NullableType$) &&
+        other is $Throwable$NullableType$;
+  }
+}
+
+final class $Throwable$Type$ extends jni$_.JType<Throwable> {
+  @jni$_.internal
+  const $Throwable$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Ljava/lang/Throwable;';
+
+  @jni$_.internal
+  @core$_.override
+  Throwable fromReference(jni$_.JReference reference) =>
+      Throwable.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const jni$_.$JObject$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<Throwable?> get nullableType => const $Throwable$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 1;
+
+  @core$_.override
+  int get hashCode => ($Throwable$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($Throwable$Type$) && other is $Throwable$Type$;
+  }
+}
+
 /// from: `java.net.URL`
 class URL extends jni$_.JObject {
   @jni$_.internal
@@ -3636,8 +4588,107 @@
   }
 }
 
+/// from: `org.chromium.net.CallbackException`
+class CallbackException extends CronetException {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<CallbackException> $type;
+
+  @jni$_.internal
+  CallbackException.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class =
+      jni$_.JClass.forName(r'org/chromium/net/CallbackException');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<CallbackException?> nullableType =
+      $CallbackException$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<CallbackException> type = $CallbackException$Type$();
+}
+
+final class $CallbackException$NullableType$
+    extends jni$_.JType<CallbackException?> {
+  @jni$_.internal
+  const $CallbackException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/CallbackException;';
+
+  @jni$_.internal
+  @core$_.override
+  CallbackException? fromReference(jni$_.JReference reference) =>
+      reference.isNull
+          ? null
+          : CallbackException.fromReference(
+              reference,
+            );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $CronetException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<CallbackException?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 5;
+
+  @core$_.override
+  int get hashCode => ($CallbackException$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($CallbackException$NullableType$) &&
+        other is $CallbackException$NullableType$;
+  }
+}
+
+final class $CallbackException$Type$ extends jni$_.JType<CallbackException> {
+  @jni$_.internal
+  const $CallbackException$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/CallbackException;';
+
+  @jni$_.internal
+  @core$_.override
+  CallbackException fromReference(jni$_.JReference reference) =>
+      CallbackException.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $CronetException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<CallbackException?> get nullableType =>
+      const $CallbackException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 5;
+
+  @core$_.override
+  int get hashCode => ($CallbackException$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($CallbackException$Type$) &&
+        other is $CallbackException$Type$;
+  }
+}
+
 /// from: `org.chromium.net.CronetException`
-class CronetException extends jni$_.JObject {
+class CronetException extends IOException {
   @jni$_.internal
   @core$_.override
   final jni$_.JType<CronetException> $type;
@@ -3677,7 +4728,7 @@
         );
   @jni$_.internal
   @core$_.override
-  jni$_.JType get superType => const jni$_.$JObject$NullableType$();
+  jni$_.JType get superType => const $IOException$NullableType$();
 
   @jni$_.internal
   @core$_.override
@@ -3685,7 +4736,7 @@
 
   @jni$_.internal
   @core$_.override
-  final superCount = 1;
+  final superCount = 4;
 
   @core$_.override
   int get hashCode => ($CronetException$NullableType$).hashCode;
@@ -3713,7 +4764,7 @@
       );
   @jni$_.internal
   @core$_.override
-  jni$_.JType get superType => const jni$_.$JObject$NullableType$();
+  jni$_.JType get superType => const $IOException$NullableType$();
 
   @jni$_.internal
   @core$_.override
@@ -3722,7 +4773,7 @@
 
   @jni$_.internal
   @core$_.override
-  final superCount = 1;
+  final superCount = 4;
 
   @core$_.override
   int get hashCode => ($CronetException$Type$).hashCode;
@@ -3734,6 +4785,329 @@
   }
 }
 
+/// from: `org.chromium.net.NetworkException`
+class NetworkException extends CronetException {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<NetworkException> $type;
+
+  @jni$_.internal
+  NetworkException.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class =
+      jni$_.JClass.forName(r'org/chromium/net/NetworkException');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<NetworkException?> nullableType =
+      $NetworkException$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<NetworkException> type = $NetworkException$Type$();
+
+  /// from: `static public final int ERROR_HOSTNAME_NOT_RESOLVED`
+  static const ERROR_HOSTNAME_NOT_RESOLVED = 1;
+
+  /// from: `static public final int ERROR_INTERNET_DISCONNECTED`
+  static const ERROR_INTERNET_DISCONNECTED = 2;
+
+  /// from: `static public final int ERROR_NETWORK_CHANGED`
+  static const ERROR_NETWORK_CHANGED = 3;
+
+  /// from: `static public final int ERROR_TIMED_OUT`
+  static const ERROR_TIMED_OUT = 4;
+
+  /// from: `static public final int ERROR_CONNECTION_CLOSED`
+  static const ERROR_CONNECTION_CLOSED = 5;
+
+  /// from: `static public final int ERROR_CONNECTION_TIMED_OUT`
+  static const ERROR_CONNECTION_TIMED_OUT = 6;
+
+  /// from: `static public final int ERROR_CONNECTION_REFUSED`
+  static const ERROR_CONNECTION_REFUSED = 7;
+
+  /// from: `static public final int ERROR_CONNECTION_RESET`
+  static const ERROR_CONNECTION_RESET = 8;
+
+  /// from: `static public final int ERROR_ADDRESS_UNREACHABLE`
+  static const ERROR_ADDRESS_UNREACHABLE = 9;
+
+  /// from: `static public final int ERROR_QUIC_PROTOCOL_FAILED`
+  static const ERROR_QUIC_PROTOCOL_FAILED = 10;
+
+  /// from: `static public final int ERROR_OTHER`
+  static const ERROR_OTHER = 11;
+  static final _id_getErrorCode = _class.instanceMethodId(
+    r'getErrorCode',
+    r'()I',
+  );
+
+  static final _getErrorCode = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract int getErrorCode()`
+  int getErrorCode() {
+    return _getErrorCode(
+            reference.pointer, _id_getErrorCode as jni$_.JMethodIDPtr)
+        .integer;
+  }
+
+  static final _id_getCronetInternalErrorCode = _class.instanceMethodId(
+    r'getCronetInternalErrorCode',
+    r'()I',
+  );
+
+  static final _getCronetInternalErrorCode =
+      jni$_.ProtectedJniExtensions.lookup<
+              jni$_.NativeFunction<
+                  jni$_.JniResult Function(
+                    jni$_.Pointer<jni$_.Void>,
+                    jni$_.JMethodIDPtr,
+                  )>>('globalEnv_CallIntMethod')
+          .asFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>();
+
+  /// from: `public abstract int getCronetInternalErrorCode()`
+  int getCronetInternalErrorCode() {
+    return _getCronetInternalErrorCode(reference.pointer,
+            _id_getCronetInternalErrorCode as jni$_.JMethodIDPtr)
+        .integer;
+  }
+
+  static final _id_immediatelyRetryable = _class.instanceMethodId(
+    r'immediatelyRetryable',
+    r'()Z',
+  );
+
+  static final _immediatelyRetryable = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallBooleanMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract boolean immediatelyRetryable()`
+  bool immediatelyRetryable() {
+    return _immediatelyRetryable(
+            reference.pointer, _id_immediatelyRetryable as jni$_.JMethodIDPtr)
+        .boolean;
+  }
+}
+
+final class $NetworkException$NullableType$
+    extends jni$_.JType<NetworkException?> {
+  @jni$_.internal
+  const $NetworkException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/NetworkException;';
+
+  @jni$_.internal
+  @core$_.override
+  NetworkException? fromReference(jni$_.JReference reference) =>
+      reference.isNull
+          ? null
+          : NetworkException.fromReference(
+              reference,
+            );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $CronetException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<NetworkException?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 5;
+
+  @core$_.override
+  int get hashCode => ($NetworkException$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($NetworkException$NullableType$) &&
+        other is $NetworkException$NullableType$;
+  }
+}
+
+final class $NetworkException$Type$ extends jni$_.JType<NetworkException> {
+  @jni$_.internal
+  const $NetworkException$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/NetworkException;';
+
+  @jni$_.internal
+  @core$_.override
+  NetworkException fromReference(jni$_.JReference reference) =>
+      NetworkException.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $CronetException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<NetworkException?> get nullableType =>
+      const $NetworkException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 5;
+
+  @core$_.override
+  int get hashCode => ($NetworkException$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($NetworkException$Type$) &&
+        other is $NetworkException$Type$;
+  }
+}
+
+/// from: `org.chromium.net.QuicException`
+class QuicException extends NetworkException {
+  @jni$_.internal
+  @core$_.override
+  final jni$_.JType<QuicException> $type;
+
+  @jni$_.internal
+  QuicException.fromReference(
+    jni$_.JReference reference,
+  )   : $type = type,
+        super.fromReference(reference);
+
+  static final _class = jni$_.JClass.forName(r'org/chromium/net/QuicException');
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<QuicException?> nullableType =
+      $QuicException$NullableType$();
+
+  /// The type which includes information such as the signature of this class.
+  static const jni$_.JType<QuicException> type = $QuicException$Type$();
+  static final _id_getQuicDetailedErrorCode = _class.instanceMethodId(
+    r'getQuicDetailedErrorCode',
+    r'()I',
+  );
+
+  static final _getQuicDetailedErrorCode = jni$_.ProtectedJniExtensions.lookup<
+          jni$_.NativeFunction<
+              jni$_.JniResult Function(
+                jni$_.Pointer<jni$_.Void>,
+                jni$_.JMethodIDPtr,
+              )>>('globalEnv_CallIntMethod')
+      .asFunction<
+          jni$_.JniResult Function(
+            jni$_.Pointer<jni$_.Void>,
+            jni$_.JMethodIDPtr,
+          )>();
+
+  /// from: `public abstract int getQuicDetailedErrorCode()`
+  int getQuicDetailedErrorCode() {
+    return _getQuicDetailedErrorCode(reference.pointer,
+            _id_getQuicDetailedErrorCode as jni$_.JMethodIDPtr)
+        .integer;
+  }
+}
+
+final class $QuicException$NullableType$ extends jni$_.JType<QuicException?> {
+  @jni$_.internal
+  const $QuicException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/QuicException;';
+
+  @jni$_.internal
+  @core$_.override
+  QuicException? fromReference(jni$_.JReference reference) => reference.isNull
+      ? null
+      : QuicException.fromReference(
+          reference,
+        );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $NetworkException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<QuicException?> get nullableType => this;
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 6;
+
+  @core$_.override
+  int get hashCode => ($QuicException$NullableType$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($QuicException$NullableType$) &&
+        other is $QuicException$NullableType$;
+  }
+}
+
+final class $QuicException$Type$ extends jni$_.JType<QuicException> {
+  @jni$_.internal
+  const $QuicException$Type$();
+
+  @jni$_.internal
+  @core$_.override
+  String get signature => r'Lorg/chromium/net/QuicException;';
+
+  @jni$_.internal
+  @core$_.override
+  QuicException fromReference(jni$_.JReference reference) =>
+      QuicException.fromReference(
+        reference,
+      );
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType get superType => const $NetworkException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  jni$_.JType<QuicException?> get nullableType =>
+      const $QuicException$NullableType$();
+
+  @jni$_.internal
+  @core$_.override
+  final superCount = 6;
+
+  @core$_.override
+  int get hashCode => ($QuicException$Type$).hashCode;
+
+  @core$_.override
+  bool operator ==(Object other) {
+    return other.runtimeType == ($QuicException$Type$) &&
+        other is $QuicException$Type$;
+  }
+}
+
 /// from: `org.chromium.net.UploadDataProviders`
 class UploadDataProviders extends jni$_.JObject {
   @jni$_.internal