Skip to content

feat: add custom exception unwrapping in interceptors#2484

Open
meylis1998 wants to merge 1 commit intocfug:mainfrom
meylis1998:feature/custom-exception-unwrapping
Open

feat: add custom exception unwrapping in interceptors#2484
meylis1998 wants to merge 1 commit intocfug:mainfrom
meylis1998:feature/custom-exception-unwrapping

Conversation

@meylis1998
Copy link

Summary

Changes

  • Add throwInnerErrorOnFinish flag to DioException (default false)
  • Add DioException.customError() factory constructor for convenient creation
  • Add rejectCustomError() method to RequestInterceptorHandler, ResponseInterceptorHandler, and ErrorInterceptorHandler
  • Unwrap marked exceptions in fetch() final catch block

Example Usage

// In interceptor
dio.interceptors.add(InterceptorsWrapper(
  onResponse: (response, handler) {
    if (response.statusCode == 401) {
      handler.rejectCustomError(
        UnauthorizedException('Token expired'),
        response.requestOptions,
      );
      return;
    }
    handler.next(response);
  },
));

// Caller can now catch custom exception directly:
try {
  await dio.get('/api');
} on UnauthorizedException catch (e) {
  // Now works!
}

Test plan

  • Added tests for rejectCustomError() from all three handler types
  • Added test verifying regular reject() still wraps in DioException
  • Added tests for DioException.customError() factory
  • Added tests for copyWith() preserving the flag
  • Added test for callFollowingErrorInterceptor parameter
  • Added test for QueuedInterceptor support
  • All existing tests pass

Closes #1950

Add mechanism to throw custom exceptions directly from interceptors
instead of wrapping them in DioException.

- Add `throwInnerErrorOnFinish` flag to DioException
- Add `DioException.customError()` factory constructor
- Add `rejectCustomError()` method to all interceptor handlers
- Unwrap marked exceptions in fetch() final catch block

This allows callers to catch custom exception types directly:

```dart
dio.interceptors.add(InterceptorsWrapper(
  onResponse: (response, handler) {
    if (response.statusCode == 401) {
      handler.rejectCustomError(
        UnauthorizedException('Token expired'),
        response.requestOptions,
      );
      return;
    }
    handler.next(response);
  },
));

// Caller can now catch custom exception directly:
try {
  await dio.get('/api');
} on UnauthorizedException catch (e) {
  // Now works!
}
```

Closes cfug#1950
@meylis1998 meylis1998 requested a review from a team as a code owner January 30, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Developer should throw custom exception in interceptor

1 participant