smart_api_errors_parser 0.1.1
smart_api_errors_parser: ^0.1.1 copied to clipboard
Maps inconsistent API error payloads into typed exceptions, form errors, and localized messages.
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.