How do I return error from a Future in dart?

FlutterDartFuture

Flutter Problem Overview


In my flutter app, I have a future that handles http requests and returns the decoded data. But I want to be able to send an error if the status code != 200 that can be gotten with the .catchError() handler.

Heres the future:

Future<List> getEvents(String customerID) async {
  var response = await http.get(
    Uri.encodeFull(...)
  );

  if (response.statusCode == 200){
    return jsonDecode(response.body);
  }else{
    // I want to return error here 
  }
}

and when I call this function, I want to be able to get the error like:

getEvents(customerID)
.then(
  ...
).catchError(
  (error) => print(error)
);

Flutter Solutions


Solution 1 - Flutter

Throwing an error/exception:

You can use either return or throw to throw an error or an exception.

  • Using return:
    Future<void> foo() async {
      if (someCondition) {
        return Future.error('FooError');
      }
    }
    
  • Using throw:
    Future<void> bar() async {
      if (someCondition) {
        throw Exception('BarException');
      }
    }
    

Catching the error/exception:

You can use either catchError or try-catch block to catch the error or the exception.

  • Using catchError:
    foo().catchError(print);
    
  • Using try-catch:
    try {
      await bar();
    } catch (e) {
      print(e);
    }
    

Solution 2 - Flutter

You can use throw :

Future<List> getEvents(String customerID) async {
  var response = await http.get(
    Uri.encodeFull(...)
  );

  if (response.statusCode == 200){
    return jsonDecode(response.body);
  }else{
    // I want to return error here 
       throw("some arbitrary error"); // error thrown
  }
}

Solution 3 - Flutter

//POST

Future<String> post_firebase_async({String? path , required Product product}) async {
    final Uri _url = path == null ? currentUrl: Uri.https(_baseUrl, '/$path');

    print('Sending a POST request at $_url');

    final response = await http.post(_url, body: jsonEncode(product.toJson()));
    if(response.statusCode == 200){
      final result = jsonDecode(response.body) as Map<String,dynamic>;
      return result['name'];
    }
    else{
      //throw HttpException(message: 'Failed with ${response.statusCode}');
      return Future.error("This is the error", StackTrace.fromString("This is its trace"));
    }

  }

Here is how to call:

  final result = await _firebase.post_firebase_async(product: dummyProduct).
  catchError((err){
    print('huhu $err');
  });

Solution 4 - Flutter

If whenComplete()’s callback throws an error, then whenComplete()’s Future completes with that error:

void main() {
  funcThatThrows()
      // Future completes with a value:
      .catchError(handleError)
      // Future completes with an error:
      .whenComplete(() => throw Exception('New error'))
      // Error is handled:
      .catchError(handleError);
}

Solution 5 - Flutter

Another way to solve this is by using the dartz package.

An example of how to use it would look something similar like this

import 'package:dartz/dartz.dart';

abstract class Failure {}
class ServerFailure extends Failure {}
class ResultFailure extends Failure {
  final int statusCode;
  const ResultFailure({required this.statusCode});
}

FutureOr<Either<Failure, List>> getEvents(String customerID) async {
  try {
    final response = await http.get(
      Uri.encodeFull(...)
    );

    if (response.statusCode == 200) {
      return Right(jsonDecode(response.body));
    } else {
      return Left(ResultFailure(statusCode: response.statusCode)); 
    }
  }
  catch (e) {
    return Left(ServerFailure());  
  }
}

main() async {
  final result = await getEvents('customerId');
  result.fold(
    (l) => print('Some failure occurred'),
    (r) => print('Success')
  );
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKingsley CAView Question on Stackoverflow
Solution 1 - FlutterCopsOnRoadView Answer on Stackoverflow
Solution 2 - Flutteranmol.majhailView Answer on Stackoverflow
Solution 3 - FlutterSolen DoganView Answer on Stackoverflow
Solution 4 - FlutterParesh MangukiyaView Answer on Stackoverflow
Solution 5 - FlutterMattiasView Answer on Stackoverflow