jala_dio

Dio adapter for Jala: captures request / response / error / cancel / progress, supports one-tap replay, and applies network throttling.

What is Jala? · Package map · Doc index

Audience Apps using Dio
Depends on jala_core, dio
Lockstep 0.8.x with jala / jala_coreCOMPAT.md
Requires Dart ^3.11

Wire the facade with jala (Jala.initialize + JalaOverlay). Brownfield: ADOPTION.md.


Install

dependencies:
  jala: ^0.8.2
  jala_dio: ^0.8.2
  dio: ^5.0.0

Setup

import 'package:dio/dio.dart';
import 'package:jala_dio/jala_dio.dart';

final dio = Dio();

// Auth (and other header mutators) BEFORE Jala so capture sees final headers.
dio.interceptors.add(AuthInterceptor());
JalaDio.attach(dio); // interceptor + replay registration

Interceptor order (common footgun)

Jala snapshots options.headers in onRequest. If auth runs after Jala, Authorization is missing from the inspector (not even ••••••).

// BAD
JalaDio.attach(dio);
dio.interceptors.add(AuthInterceptor());

// GOOD
dio.interceptors.add(AuthInterceptor());
JalaDio.attach(dio);

Details: TROUBLESHOOTING.md.

Capture only (no replay)

dio.interceptors.add(JalaDioInterceptor());

Replay stays disabled until something registers a replayer via JalaDio.attach.


Public API

API Role
JalaDio.attach(dio) Add interceptor + register JalaDioReplayer
JalaDioInterceptor Capture-only interceptor
JalaDioReplayer Re-issue stored calls through the same Dio

Reads JalaBinding.instance at call time (configured by Jala.initialize).


Behavior notes

Replay

Rebuilds RequestOptions and re-issues through the same Dio (interceptors run again). New entry gets replayOf set. Masked headers and query params are not resent.

Multiple clients: last JalaDio.attach / JalaHttp.wrap wins for the Replay button. Attach every Dio you want captured; attach the primary API client last. ADOPTION — multiple Dio.

Throttling

Uses JalaThrottleRegistry when a profile is active and the host matches:

  • Drop (e.g. Offline) → connection-error DioException before the adapter
  • Latency (± jitter) before forward
  • Bandwidth (up and down) applies to every response type. A ResponseType.stream response is paced chunk by chunk; a buffered one is resolved to bytes inside Dio's own transformer, off a stream the interceptor never sees, so it is instead held for the time those bytes would have taken. End-to-end timing matches either way; only buffered responses lack progressive delivery.

Production safety

  • No-op when !isEnabled
  • Capture in try/catch; always forward exactly once
  • Redaction + body caps via JalaConfigCONFIG.md

See also

Libraries

jala_dio
Dio interceptor for Jala, the in-app Flutter network inspector.