P-RAD
P-RAD

Reputation: 1341

How to catch exception in flutter?

This is my exception class. Exception class has been implemented by the abstract exception class of flutter. Am I missing something?

class FetchDataException implements Exception {
 final _message;
 FetchDataException([this._message]);

String toString() {
if (_message == null) return "Exception";
  return "Exception: $_message";
 }
}


void loginUser(String email, String password) {
  _data
    .userLogin(email, password)
    .then((user) => _view.onLoginComplete(user))
    .catchError((onError) => {
       print('error caught');
       _view.onLoginError();
    });
}

Future < User > userLogin(email, password) async {
  Map body = {
    'username': email,
    'password': password
  };
  http.Response response = await http.post(apiUrl, body: body);
  final responseBody = json.decode(response.body);
  final statusCode = response.statusCode;
  if (statusCode != HTTP_200_OK || responseBody == null) {
    throw new FetchDataException(
      "An error occured : [Status Code : $statusCode]");
   }
  return new User.fromMap(responseBody);
}

CatchError doesn't catch the error when the status is not 200. In short error caught is not printed.

Upvotes: 51

Views: 115266

Answers (5)

Zia
Zia

Reputation: 683

You can throw exception as below as well.

 Future.error('Location permissions are denied');

More important, Sometimes you may face to a situation where you want to take action on certain exceptions.

Example:

  _getCurrentLocation() async {
    try {
      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          throw Exception("Location permissions are denied");
          //Future.error('Location permissions are denied');
        }
      }

      if (permission == LocationPermission.deniedForever) {
        throw Exception("Location permissions permanently denied.");
        //Future.error('Location permissions permanently denied.');
      }

      Position pos = await Geolocator.getCurrentPosition();
      _currentPosition = LatLng(pos.latitude, pos.longitude);
    } on Exception catch (e) {
      String message = e.toString();
      if (message == "Location permissions are denied") {
        print("Action on denied location");
        return;
      }
      if (message == "Location permissions permanently denied.") {
        print("Action on permanently denied location");
        return;
      }

    }

Upvotes: 0

Lucas Lombardi
Lucas Lombardi

Reputation: 129

I was trying to find this answer when got to this page, hope it helps: https://stackoverflow.com/a/57736915/12647239

Basicly i was just trying to catch an error message from a method, but i was calling

throw Exception("message")

And in "catchError" i was getting "Exception: message" instead of "message".

catchError(
  (error) => print(error)
);

fixed with the return in the above reference

Upvotes: 2

CopsOnRoad
CopsOnRoad

Reputation: 267474

Let's say this is your function which throws an exception:

Future<void> foo() async {
  throw Exception('FooException');
}

You can either use try-catch block or catchError on the Future since both do the same thing.

  • Using try-catch

    try {
      await foo();
    } on Exception catch (e) {
      print(e); // Only catches an exception of type `Exception`.
    } catch (e) {
      print(e); // Catches all types of `Exception` and `Error`.
    }
    
  • Use catchError

    await foo().catchError(print);
    

Upvotes: 21

Muhammad Ashraf
Muhammad Ashraf

Reputation: 3649

Future < User > userLogin(email, password) async { try {
  Map body = {
    'username': email,
    'password': password
  };
  http.Response response = await http.post(apiUrl, body: body);
  final responseBody = json.decode(response.body);
  final statusCode = response.statusCode;
  if (statusCode != HTTP_200_OK || responseBody == null) {
    throw new FetchDataException(
      "An error occured : [Status Code : $statusCode]");
   }
  return new User.fromMap(responseBody); }
   catch (e){
    print(e.toString());
}

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657238

Try

void loginUser(String email, String password) async {
  try {
    var user = await _data
      .userLogin(email, password);
    _view.onLoginComplete(user);
      });
  } on FetchDataException catch(e) {
    print('error caught: $e');
    _view.onLoginError();
  }
}

catchError is sometimes a bit tricky to get right. With async/await you can use try/catch like with sync code and it is usually much easier to get right.

Upvotes: 78

Related Questions