parseResponse<T> function
解析响应: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);
}