使用RxDart处理API调用各HTTP错误码响应的实现疑问
处理RxDart中API调用的HTTP状态码区分逻辑
核心思路是在拿到HTTP响应的第一环节就判断状态码,将4xx、5xx错误转换为不同类型的自定义异常,后续在错误捕获逻辑中区分处理。以下是调整后的代码:
步骤1:定义自定义异常类
先创建两个异常类,用于区分客户端错误(4xx)和服务端错误(5xx):
class ClientException implements Exception { final String message; final Uri url; ClientException(this.message, this.url); @override String toString() => 'ClientException: $message, URL: $url'; } class ServerException implements Exception { final String message; final Uri url; ServerException(this.message, this.url); @override String toString() => 'ServerException: $message, URL: $url'; }
步骤2:调整API调用链
在第一个处理response的回调中加入状态码判断,抛出对应异常,后续在catchError中区分处理:
http .get("http://www.api.com/api/?q=$text") .then((response) { // 先校验HTTP状态码 if (response.statusCode >= 400 && response.statusCode < 500) { throw ClientException('客户端错误: ${response.statusCode}', response.request!.url); } else if (response.statusCode >= 500) { throw ServerException('服务端错误: ${response.statusCode}', response.request!.url); } return response.body; }) .then(JSON.decode) .then((map) => map["results"]) .then((list) { list.forEach(_addItem); }) .catchError((error) { // 区分不同异常类型处理 if (error is ClientException) { // 处理4xx错误,比如提示参数错误、权限不足等 _onClientError(error); } else if (error is ServerException) { // 处理5xx错误,比如提示服务端异常 _onServerError(error); } else { // 处理其他网络错误(比如连接超时、无网络等) _onError(error); } }) .whenComplete(() { // 不管成功失败,最终都更新加载状态 setState(() { _isLoading = false; }); });
(可选)基于RxDart Observable的写法
如果用RxDart的Observable链式操作,写法更贴合响应式风格:
import 'package:rxdart/rxdart.dart'; Observable.fromFuture(http.get("http://www.api.com/api/?q=$text")) .map((response) { if (response.statusCode >= 400 && response.statusCode < 500) { throw ClientException('客户端错误: ${response.statusCode}', response.request!.url); } else if (response.statusCode >= 500) { throw ServerException('服务端错误: ${response.statusCode}', response.request!.url); } return response.body; }) .map(JSON.decode) .map((map) => map["results"]) .doOnData((list) => list.forEach(_addItem)) .doOnError((error, stackTrace) { if (error is ClientException) { _onClientError(error); } else if (error is ServerException) { _onServerError(error); } else { _onError(error); } }) .doOnDone(() => setState(() => _isLoading = false)) .subscribe();
关键说明
- 必须在解析响应体之前判断状态码:因为4xx/5xx响应可能返回错误格式的body,提前判断能避免后续解析失败。
- 自定义异常能让错误处理逻辑更清晰,避免用字符串判断状态码的繁琐。
whenComplete(或RxDart的doOnDone)比最后一个then语义更准确,确保不管请求成功还是失败,都会更新加载状态。
内容的提问来源于stack exchange,提问作者Zeus
相关产品推荐
相关产品推荐

