Home > Enterprise >  How to return catch exception in flutter
How to return catch exception in flutter

Time:11-10

I working on error handling of api's. i want if api is crashed then it display a message of "Server is down" something like this, in UI.

I created a class where i'm creating methods of api, here in getBooks method if i modify the api url then it is printing this Exception, and i want it in UI. The problem is getBooks return type is List<Book>> so we can't return this Exception, any solution how to do this?

Exception
E/flutter (12924): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Exception

here is my api code

class BooksApi {
  static Future<List<Book>> getBooks(String query) async {
    try {
      final url = Uri.parse(
          'https://gist.githubusercontent.com/JohannesMilke/d53fbbe9a1b7e7ca2645db13b995dc6f/raw/eace0e20f86cdde3352b2d92f699b6e9dedd8c70/books.json');
      final response = await http.get(url);

      if (response.statusCode == 200) {
        final List books = json.decode(response.body);

        return books.map((json) => Book.fromJson(json)).where((book) {
          final titleLower = book.title.toLowerCase();
          final authorLower = book.author.toLowerCase();
          final searchLower = query.toLowerCase();

          return titleLower.contains(searchLower) ||
              authorLower.contains(searchLower);
        }).toList();
      } else {
        throw Exception;
      }
    } catch (e) {
      print("e");
      print(e);
      
       
    }
  
    throw Exception;
  }
}

and calling it like

Future init() async {
    setState(() {
      isLoading = true;
    });
    var books = await BooksApi.getBooks(query); //this
    
    var response = await obj.getProduct();
    print(response);
    setState(() => this.books = books);
    setState(() {
      isLoading = false;
    });
  }

CodePudding user response:

You could handle errors with then and onError :

await BooksApi.getBooks(query).then((books) async {
  setState(() => {
    this.books = books;
    this.isLoading = false;
  })
}, one rror: (error) {
  // do something with error
});

or a simple try-catch (you can write try-catch clauses the same way you would in synchronous code).

See handling errors.

You can also use catchError id you don't use async/await :

BooksApi.getBooks(query).then((books) { 
  setState(() => {
    this.books = books;
    this.isLoading = false;
  })
}).catchError((error, stackTrace) {
  print("error is: $error");
});

See futures error handling.

CodePudding user response:

Try to wrap 'var books = await BooksApi.getBooks(query)' with try and catch.

...
try {
   var books = await BooksApi.getBooks(query);
} catch (e) {
   // To do for UI
}
...

CodePudding user response:

For api, you need to make something like this:

APIModel{
  final int code;
// or a success flag
// final bool success;
final String message;
final List<Book> data;
APIModel({this.code,this.message,this.data});
}

It means, every api have its own code,message,and data filed.
When you request, you can check your code or success:

var response = await request(params);
isLoading = false;
if(response.code == 0){}
// or
if(response.success){
  // do what you want
}
else {
 Toast.show(response.message);
}

You can use build_runner and json_serializable.

  • Related