send method
Send a request and return the parsed JSON body (Map, List, or null).
Throws a typed NorbixError subclass on non-2xx responses or transport failures.
Implementation
Future<Object?> send({
required String route,
String method = 'GET',
Map<String, Object?>? query,
Object? body,
Map<String, String>? headers,
Map<String, Object?>? pathParams,
}) async {
final url = _resolveUrl(route: route, query: query, pathParams: pathParams);
final allHeaders = _buildHeaders(headers);
final encodedBody = (body == null || method.toUpperCase() == 'GET')
? null
: jsonEncode(body);
final request = HttpDriverRequest(
method: method,
url: url,
headers: allHeaders,
body: encodedBody,
timeout: config.timeout,
);
Object? lastError;
for (var attempt = 0; attempt <= config.maxRetries; attempt++) {
try {
final response = await _driver.send(request);
if (response.statusCode >= 500 || response.statusCode == 429) {
if (attempt < config.maxRetries) {
await Future<void>.delayed(_backoff(attempt));
continue;
}
}
return _parseResponse(response);
} on NorbixError {
rethrow;
} on SocketException catch (e) {
lastError = NorbixTransportError(
message: 'Network error: ${e.message}',
details: {'osError': e.osError?.message},
);
if (attempt < config.maxRetries) {
await Future<void>.delayed(_backoff(attempt));
continue;
}
throw lastError;
} catch (e) {
lastError = NorbixTransportError(
message: 'Transport failure: $e',
details: const {},
);
if (attempt < config.maxRetries) {
await Future<void>.delayed(_backoff(attempt));
continue;
}
throw lastError;
}
}
throw lastError as Object;
}