You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:05:11