Flutter抛出异常的最佳实践 如何避免Exception前缀重复
问题根因
你代码中每次捕获异常时都会执行throw Exception(e)操作,该操作会把捕获到的原有异常的字符串描述,拼接到新创建的Exception实例的默认前缀Exception: 之后,4层调用链路每层都做一次包装,最终就会出现4个重复的Exception: 前缀。
正确的异常抛出方案
方案1:无额外信息补充时直接使用rethrow重抛
如果捕获异常后不需要追加自定义的错误上下文,只是要把异常继续向上传递,直接用Dart内置的rethrow关键字即可,不会额外包装异常。
修改后的代码示例:
getSomeData () async { try { await myFunction3(); } catch (e) { // 无额外信息补充直接重抛 rethrow; } } Future<void> myFunction3 () async { try { await myFunction2(); } catch (e) { rethrow; } } Future<void> myFunction2 () async { try { await myFunction1(); } catch (e) { rethrow; } } Future<void> myFunction1() async { try { await dio.get(/*some parameters*/); } on DioError catch (e) { // 仅在最底层做一次异常转换,不需要额外包装的话也可以直接rethrow DioError throw e.error; } catch (e) { rethrow; } }
修改后最终抛出的错误信息就是原生的:SocketException: OS Error: Connection refused, errno = 111, address = 10.12.7.15, port = 39682,不会有多余的前缀。
方案2:需要补充上下文时仅做一次包装
如果需要给异常追加业务相关的提示信息,仅在最上层或者你需要的某一层做一次Exception包装即可,其他层仍然用rethrow:
示例代码:
getSomeData () async { try { await myFunction3(); } catch (e) { // 仅在最上层加一次自定义信息包装 throw Exception("获取业务数据失败,底层错误:$e"); } } // 下层所有函数的catch块都直接rethrow,不做额外包装 Future<void> myFunction3 () async { try { await myFunction2(); } catch (e) { rethrow; } } // 其余下层函数同理都用rethrow
最终错误信息只会有一个Exception:前缀:Exception: 获取业务数据失败,底层错误:SocketException: OS Error: Connection refused, errno = 111, address = 10.12.7.15, port = 39682
方案3:自定义异常类型规避默认前缀
如果不想用Dart默认的Exception前缀,可以自定义业务异常类:
class AppException implements Exception { final String message; AppException(this.message); // 重写toString方法,不需要额外加前缀 @override String toString() => message; }
使用时直接抛出AppException("你的错误信息")即可,不会出现重复前缀。
内容的提问来源于stack exchange,提问作者arrmani88
相关产品推荐
相关产品推荐

