parseResponse<T> function

T parseResponse<T>(
  1. HttpResponseData response
)

解析响应:2xx 返回 JSON(204 和空响应为 null);错误转为 DRException。

Implementation

T parseResponse<T>(HttpResponseData response) {
  final text = response.body.isEmpty ? '' : utf8.decode(response.body, allowMalformed: true);
  Object? data;
  if (text.isNotEmpty) {
    try {
      data = jsonDecode(text);
    } catch (_) {
      data = null;
    }
  }
  final status = response.status;
  if (status >= 200 && status < 300) {
    if (status == 204 || text.isEmpty) return null as T;
    if (data == null) throw DRException(code: 'internal', message: 'invalid response body', status: status, source: ErrorSource.http);
    return _normalizeCursor(data) as T;
  }
  final retryAfter = parseRetryAfter(response.headers['retry-after']);
  final error = data is Map ? data['error'] : null;
  if (error is Map && error['code'] is String) {
    final details = error['details'] is Map ? (error['details'] as Map).cast<String, Object?>() : null;
    final retryFromDetails = details?['retry_after_seconds'];
    throw DRException(
      code: error['code'] as String,
      message: error['message'] is String ? error['message'] as String : null,
      details: details,
      status: status,
      requestId: error['request_id'] is String ? error['request_id'] as String : response.headers['x-request-id'],
      retryAfter: retryAfter ?? (retryFromDetails is num ? retryFromDetails.ceil() : null),
      source: ErrorSource.http,
    );
  }
  // 网关、代理返回的 HTML 等:5xx 为 internal,其他为 network_error
  throw DRException(code: status >= 500 ? 'internal' : LocalErrorCode.networkError, message: 'HTTP $status', status: status, retryAfter: retryAfter, source: ErrorSource.http);
}