uploadBlob method
Uploads a single attachment with retries.
Implementation
Future<BlobUploadResult> uploadBlob(BlobFile file) {
const label = 'attachment upload';
final url = Uri.parse(
'${config.baseURL}/projects/${config.projectId}/blobs',
);
return withUploadRetry('$label (${file.fileName})', () async {
final MultipartBody body;
try {
body = openMultipart(file);
} on FileSystemException catch (error) {
throw ApiError('$label failed: $error', retryable: false);
}
final _Response response;
try {
response = await _send(
'POST',
url,
headers: <String, String>{
'Authorization': 'Bearer ${config.token}',
'Content-Type': body.contentType,
},
bodyStream: body.stream,
contentLength: body.length,
timeout: httpUploadTimeout,
);
} on FileSystemException catch (error) {
throw ApiError('$label failed: $error', retryable: false);
} on Object catch (error) {
throw ApiError('$label failed: $error');
}
if (response.statusCode >= 400) {
throw ApiError(
'$label failed: HTTP ${response.statusCode} ${response.body.trim()}',
);
}
final json = _decodeObject(response.body, label);
final fileName = json['fileName'];
final mimeType = json['mimeType'];
final sizeBytes = json['sizeBytes'];
return BlobUploadResult(
id: (json['id'] as String?) ?? '',
fileName: fileName is String && fileName.isNotEmpty
? fileName
: file.fileName,
mimeType: mimeType is String && mimeType.isNotEmpty
? mimeType
: (file.mimeType.isEmpty ? defaultMimeType : file.mimeType),
sizeBytes: sizeBytes is int ? sizeBytes : 0,
);
});
}