Flutter中已做异常处理仍崩溃,需实现异常时显示Toast提示
问题分析与修复方案
1. 修复拼写错误引发的未捕获异常
你的GETQuotes方法里存在拼写错误:reurnJson应为returnJson。这个错误会触发NoSuchMethodError,而该异常不在你捕获的SocketException范围内,会直接向上抛出导致应用崩溃,且无法被后续onError捕获。
修复后的GETQuotes方法:
Future<dynamic> GETQuotes(String url, {int skip = 0, int limit = 10}) async { dynamic responseData; try { final response = await http.get(Uri.parse(url)); responseData = returnJson(response); // 修正拼写错误 } on SocketException { throw FetchDataException("No internet connection"); } catch (e) { // 兜底捕获其他所有异常,统一封装后抛出 throw FetchDataException(e.toString()); } return responseData; }
2. 移除无意义的rethrow操作
QuoteRepo的getQuoteAPI方法中,所有捕获的异常都直接rethrow,相当于没有做任何实际处理,完全可以简化代码:
class QuoteRepo { final NetworkApi _networkApi = NetworkApi(); Future<dynamic> getQuoteAPI(int limit, int skip) async { return await _networkApi.GETQuotes( "${APPURL.quoteEndPointURL}limit=$limit&skip=$skip"); } }
如果需要在这里对特定异常做额外处理(比如日志),可以修改为:
Future<dynamic> getQuoteAPI(int limit, int skip) async { try { return await _networkApi.GETQuotes( "${APPURL.quoteEndPointURL}limit=$limit&skip=$skip"); } on FetchDataException catch (e) { // 可在此添加日志记录等操作 rethrow; // 继续传递异常给上层显示Toast } catch (e) { throw FetchDataException("请求出错:${e.toString()}"); } }
3. 避免await与then/onError混合使用
getQuote方法同时使用await和then/onError会导致异常处理逻辑混乱:await会将Future的异常转化为同步异常,不会触发onError回调。推荐改用以下两种方式之一:
方案一:使用try-catch(更直观)
Future<void> getQuote({int limit = 0, int skip = 0}) async { try { final data = await _quoteRepo.getQuoteAPI(limit, skip); print(data.toString()); } catch (error) { Utils.showToastMessage(error.toString()); } }
方案二:单独使用then/onError
Future<void> getQuote({int limit = 0, int skip = 0}) async { _quoteRepo.getQuoteAPI(limit, skip) .then((value) { print(value.toString()); }) .onError((error, stackTrace) { Utils.showToastMessage(error.toString()); }); }
4. 确保自定义异常类正确实现
检查你的自定义异常类(如FetchDataException)是否正确继承自Exception,示例:
class FetchDataException implements Exception { final String message; FetchDataException(this.message); @override String toString() => message; }
这样才能保证异常信息能通过toString()正确获取并显示在Toast中。
内容的提问来源于stack exchange,提问作者Jeevan Shrestha
相关产品推荐
相关产品推荐

