safeCall<T> method

  1. @override
Future<Result<T>> safeCall<T>(
  1. Future<T> request(), {
  2. Result<T>? onError(
    1. Object error
    )?,
})
override

Safely executes a Supabase operation and returns a Result.

  • On success: Returns Ok(result)
  • On failure: Returns Err(Failure) based on the error registry mappings

The error handling priority is:

  1. onError callback (if provided) for custom handling
  2. Error registry mappings (auth, postgrest, storage, function, general)
  3. For unrecognized exceptions: the realtime hook, then transport-level classification (isTransportErrortransportError) — see _handleGeneralException for the full precedence.
  4. SupabaseErrorRegistry.genericError as fallback

Example:

final result = await handler.safeCall(
  () => supabase.from('users').select().eq('id', userId).single(),
  onError: (error) {
    // Custom handling for specific cases
    if (error is PostgrestException && error.code == 'PGRST116') {
      return const Err(UserNotFoundFailure());
    }
    return null; // Fall through to registry
  },
);

Implementation

@override
Future<Result<T>> safeCall<T>(
  Future<T> Function() request, {
  Result<T>? Function(Object error)? onError,
}) async {
  callCount++;
  final next = _queue.isNotEmpty ? _queue.removeAt(0) : defaultResult;
  if (next == null) {
    throw StateError(
      'FakeSupabaseHandler: no queued result for call #$callCount. '
      'Call enqueueOk/enqueueErr before exercising the code under test, '
      'or set defaultResult.',
    );
  }
  return next.fold((failure) => Err<T>(failure), (value) => Ok<T>(value as T));
}