code quality improvements and improved file error handling
This commit is contained in:
64
src/components/SettingForms/System/Upload.ts
Normal file
64
src/components/SettingForms/System/Upload.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
// CORS (server missing Access-Control-Allow-* headers)??
|
||||
|
||||
type BlobFileUpload = {
|
||||
file: File | null;
|
||||
opts?: {
|
||||
timeoutMs?: number;
|
||||
fieldName?: string;
|
||||
overrideFileName?: string;
|
||||
uploadUrl: URL | string;
|
||||
};
|
||||
};
|
||||
|
||||
export async function sendBlobFileUpload({
|
||||
file,
|
||||
opts,
|
||||
}: BlobFileUpload): Promise<string> {
|
||||
if (!file) throw new Error("No file supplied");
|
||||
if (!opts?.uploadUrl) throw new Error("No URL supplied");
|
||||
|
||||
if (file?.type !== "text/csv") {
|
||||
throw new Error("This file is not supported, please upload a CSV file.");
|
||||
}
|
||||
const timeoutMs = opts?.timeoutMs ?? 30000;
|
||||
const fieldName = opts?.fieldName ?? "upload";
|
||||
const fileName = opts?.overrideFileName ?? file?.name;
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||||
|
||||
try {
|
||||
const form = new FormData();
|
||||
|
||||
form.append(fieldName, file, fileName);
|
||||
|
||||
const resp = await fetch(opts?.uploadUrl, {
|
||||
method: "POST",
|
||||
body: form,
|
||||
signal: controller.signal,
|
||||
redirect: "follow",
|
||||
});
|
||||
|
||||
const bodyText = await resp.text();
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Upload failed (${resp.status} ${resp.statusText}) from ${opts.uploadUrl} — ${bodyText}`
|
||||
);
|
||||
}
|
||||
return bodyText;
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof DOMException && err.name === "AbortError") {
|
||||
throw new Error(`Timeout uploading to ${opts.uploadUrl}.`);
|
||||
}
|
||||
// In browsers, fetch throws TypeError on network-level failures
|
||||
if (err instanceof TypeError) {
|
||||
throw new Error(
|
||||
`HTTP error uploading to ${opts.uploadUrl}: ${err.message}`
|
||||
);
|
||||
}
|
||||
throw new Error("HTTP method POST is not supported by this URL");
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user