smart_api_errors_parser

Normalize inconsistent API error responses into form errors, global errors, localized messages, and typed exceptions. Optional Dio integration included.

Complete standalone runnable Flutter app: example/.

Map a response

final errors = ApiErrorMapper.map(
  response.data,
  schema: ApiErrorSchema.nestedMap,
);

formController.setErrors(errors.fieldErrors);
showSnackbar(errors.userMessage);

Auto-detection supports nested maps and detail lists:

{"errors":{"email":["Already registered"]}}
{
  "message":"Validation failed",
  "details":[{"field":"email","message":"Already used"}]
}

Dio integration

dio.interceptors.add(
  ApiErrorInterceptor(
    mapper: ApiErrorMapper(
      localizer: (error) => translations[error.code] ?? error.message,
    ),
  ),
);

try {
  await repository.register(data);
} on ApiValidationException catch (error) {
  formController.setErrors(
    error.fields,
    scrollToFirstError: true,
  );
} on ApiException catch (error) {
  showSnackbar(error.message);
}

At repository boundary, unwrap each Dio request:

Future<void> register(Map<String, Object?> data) async {
  await dio.post<void>('/register', data: data).unwrapApiErrors();
}

Dio always emits DioException for failed request futures. unwrapApiErrors() extracts and throws mapped exception, enabling direct on ApiValidationException catches. Without unwrapping, original DioException remains available and mapped ApiException is in error.error. Cancelled requests remain DioException values so cancellation can be handled independently from network failures.

HTTP status classification takes priority over payload shape. For example, a 401 response containing an errors map still becomes ApiAuthenticationException, not ApiValidationException.

Custom backend shape

final mapper = ApiErrorMapper(
  customParser: (data) sync* {
    final body = data as Map<String, dynamic>;
    for (final entry in (body['problems'] as Map).entries) {
      yield ApiErrorMessage(
        field: entry.key.toString(),
        message: entry.value.toString(),
      );
    }
  },
);

Exceptions thrown by customParser intentionally propagate. This keeps schema implementation errors visible instead of converting them into generic user messages.

Libraries

smart_api_errors_parser
Normalizes API failures into typed exceptions and UI-ready messages.