add upload logs
This commit is contained in:
parent
214ac28926
commit
9449a45ef9
|
|
@ -42,18 +42,38 @@ export const PresubmitStep = ({ prevStep }: PresubmitStepProps) => {
|
|||
setIsErrorUploadModal(false);
|
||||
uploadFile.resetUploadError();
|
||||
uploadCover.resetUploadError();
|
||||
console.info("[App2Client][Presubmit] Пользователь закрыл модалку ошибок загрузки");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (uploadFile.uploadError || uploadCover.uploadError) {
|
||||
console.error("[App2Client][Presubmit] Обнаружены ошибки загрузки", {
|
||||
fileError: uploadFile.uploadError,
|
||||
coverError: uploadCover.uploadError,
|
||||
});
|
||||
setIsErrorUploadModal(true);
|
||||
}
|
||||
}, [uploadFile.uploadError, uploadCover.uploadError]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
console.info("[App2Client][Presubmit] Начинаем отправку контента", {
|
||||
name: rootStore.name,
|
||||
author: rootStore.author,
|
||||
fileName: rootStore.file?.name,
|
||||
fileSize: rootStore.file?.size,
|
||||
fileType: rootStore.file?.type,
|
||||
allowCover: rootStore.allowCover,
|
||||
hasCover: Boolean(rootStore.cover),
|
||||
allowDownload: rootStore.allowDwnld,
|
||||
hashtags: rootStore.hashtags,
|
||||
royaltyCount: rootStore.royalty.length,
|
||||
allowResale: rootStore.allowResale,
|
||||
});
|
||||
|
||||
let coverUploadResult = { content_id_v1: "" };
|
||||
|
||||
console.info("[App2Client][Presubmit] Загружаем основной файл через tus");
|
||||
const fileUploadResult = await uploadFile.mutateAsync({
|
||||
file: rootStore.file as File,
|
||||
metadata: {
|
||||
|
|
@ -70,12 +90,37 @@ export const PresubmitStep = ({ prevStep }: PresubmitStepProps) => {
|
|||
throw new Error("Tus upload did not return encrypted cid");
|
||||
}
|
||||
|
||||
console.info("[App2Client][Presubmit] Основной файл загружен", {
|
||||
encryptedCid: fileUploadResult.encryptedCid,
|
||||
uploadId: fileUploadResult.uploadId,
|
||||
state: fileUploadResult.state,
|
||||
sizeBytes: fileUploadResult.sizeBytes,
|
||||
});
|
||||
|
||||
if (rootStore.allowCover && rootStore.cover) {
|
||||
console.info("[App2Client][Presubmit] Начинаем загрузку обложки", {
|
||||
fileName: rootStore.cover.name,
|
||||
fileSize: rootStore.cover.size,
|
||||
fileType: rootStore.cover.type,
|
||||
});
|
||||
coverUploadResult = await uploadCover.mutateAsync(
|
||||
rootStore.cover as File,
|
||||
);
|
||||
|
||||
console.info("[App2Client][Presubmit] Обложка загружена", {
|
||||
contentIdV1: coverUploadResult.content_id_v1,
|
||||
});
|
||||
} else {
|
||||
console.info("[App2Client][Presubmit] Обложка не загружается", {
|
||||
allowCover: rootStore.allowCover,
|
||||
hasCoverFile: Boolean(rootStore.cover),
|
||||
});
|
||||
}
|
||||
|
||||
console.info("[App2Client][Presubmit] Отправляем метаданные контента", {
|
||||
downloadable: rootStore.allowDwnld,
|
||||
coverIncluded: Boolean(coverUploadResult.content_id_v1),
|
||||
});
|
||||
const createContentResponse = await createContent.mutateAsync({
|
||||
title: rootStore.name,
|
||||
|
||||
|
|
@ -112,6 +157,10 @@ export const PresubmitStep = ({ prevStep }: PresubmitStepProps) => {
|
|||
|
||||
if (createContentResponse.data) {
|
||||
if (createContentResponse.data.address != "free") {
|
||||
console.info("[App2Client][Presubmit] Отправляем транзакцию через TonConnect", {
|
||||
address: createContentResponse.data.address,
|
||||
amount: createContentResponse.data.amount,
|
||||
});
|
||||
const transactionResponse = await tonConnectUI.sendTransaction({
|
||||
validUntil: Math.floor(Date.now() / 1000) + 120,
|
||||
messages: [
|
||||
|
|
@ -123,19 +172,29 @@ export const PresubmitStep = ({ prevStep }: PresubmitStepProps) => {
|
|||
],
|
||||
});
|
||||
if (transactionResponse.boc) {
|
||||
console.info("[App2Client][Presubmit] Транзакция успешно отправлена", {
|
||||
bocLength: transactionResponse.boc.length,
|
||||
});
|
||||
WebApp.close();
|
||||
} else {
|
||||
console.error("Transaction failed:", transactionResponse);
|
||||
console.error("[App2Client][Presubmit] Транзакция не отправлена", {
|
||||
response: transactionResponse,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.info("[App2Client][Presubmit] Завершаем процесс и закрываем WebApp");
|
||||
WebApp.close();
|
||||
// @ts-expect-error Type issues
|
||||
} catch (error: never) {
|
||||
|
||||
|
||||
console.error("An error occurred during the submission process:", error);
|
||||
console.error("[App2Client][Presubmit] Ошибка во время отправки", {
|
||||
error,
|
||||
});
|
||||
|
||||
if (error?.status === 400) {
|
||||
alert(
|
||||
|
|
|
|||
|
|
@ -20,8 +20,20 @@ type UseCreateNewContentPayload = {
|
|||
export const useCreateNewContent = () => {
|
||||
return useMutation(
|
||||
["create-new-content"],
|
||||
(payload: UseCreateNewContentPayload) => {
|
||||
return request.post<{
|
||||
async (payload: UseCreateNewContentPayload) => {
|
||||
console.info("[App2Client][Content] Отправляем контент на создание", {
|
||||
title: payload.title,
|
||||
hasImage: Boolean(payload.image),
|
||||
contentCid: payload.content,
|
||||
hashtags: payload.hashtags,
|
||||
authorsCount: payload.authors.length,
|
||||
royaltyCount: payload.royaltyParams.length,
|
||||
downloadable: payload.downloadable,
|
||||
allowResale: payload.allowResale,
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await request.post<{
|
||||
address: string;
|
||||
amount: string;
|
||||
payload: string;
|
||||
|
|
@ -30,6 +42,22 @@ export const useCreateNewContent = () => {
|
|||
Authorization: localStorage.getItem('auth_v1_token') ?? ""
|
||||
}
|
||||
});
|
||||
|
||||
console.info("[App2Client][Content] Сервер вернул данные для транзакции", {
|
||||
title: payload.title,
|
||||
hasAddress: Boolean(response.data.address),
|
||||
amount: response.data.amount,
|
||||
payloadLength: response.data.payload?.length ?? 0,
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("[App2Client][Content] Ошибка при создании контента", {
|
||||
title: payload.title,
|
||||
error,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -94,8 +94,16 @@ const pollUploadStatus = async (
|
|||
signal?: AbortSignal,
|
||||
): Promise<UploadStatusResponse> => {
|
||||
const startedAt = Date.now();
|
||||
let attempt = 0;
|
||||
|
||||
console.info("[App2Client][TusUpload] Запускаем polling статуса", {
|
||||
uploadId,
|
||||
intervalMs: TUS_STATUS_POLL_INTERVAL_MS,
|
||||
timeoutMs: TUS_STATUS_POLL_TIMEOUT_MS,
|
||||
});
|
||||
|
||||
while (true) {
|
||||
attempt += 1;
|
||||
if (signal?.aborted) {
|
||||
throw new DOMException("Tus status polling aborted", "AbortError");
|
||||
}
|
||||
|
|
@ -108,25 +116,58 @@ const pollUploadStatus = async (
|
|||
},
|
||||
);
|
||||
|
||||
console.info("[App2Client][TusUpload] Получен статус tus", {
|
||||
uploadId,
|
||||
attempt,
|
||||
state: data.state,
|
||||
hasEncryptedCid: Boolean(data.encrypted_cid),
|
||||
});
|
||||
|
||||
if (data.state === "failed") {
|
||||
throw new Error(data.error || "Tus upload failed on server");
|
||||
}
|
||||
|
||||
if (data.state === "pinned" && data.encrypted_cid) {
|
||||
console.info("[App2Client][TusUpload] Статус tus завершен", {
|
||||
uploadId,
|
||||
state: data.state,
|
||||
encryptedCid: data.encrypted_cid,
|
||||
sizeBytes: data.size_bytes,
|
||||
attempts: attempt,
|
||||
durationMs: Date.now() - startedAt,
|
||||
});
|
||||
return data;
|
||||
}
|
||||
} catch (error) {
|
||||
const maybeAxios = error as { response?: { status?: number } };
|
||||
if (maybeAxios?.response?.status === 404) {
|
||||
// Hook has not recorded the upload session yet; continue polling.
|
||||
console.info("[App2Client][TusUpload] Статус tus еще не готов (404)", {
|
||||
uploadId,
|
||||
attempt,
|
||||
});
|
||||
} else if (error instanceof DOMException && error.name === "AbortError") {
|
||||
console.warn("[App2Client][TusUpload] Поллинг tus прерван", {
|
||||
uploadId,
|
||||
attempt,
|
||||
});
|
||||
throw error;
|
||||
} else {
|
||||
console.error("[App2Client][TusUpload] Ошибка во время polling", {
|
||||
uploadId,
|
||||
attempt,
|
||||
error,
|
||||
});
|
||||
throw normalizeError(error, "Tus status polling failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (Date.now() - startedAt > TUS_STATUS_POLL_TIMEOUT_MS) {
|
||||
console.error("[App2Client][TusUpload] Поллинг tus превысил таймаут", {
|
||||
uploadId,
|
||||
attempts: attempt,
|
||||
durationMs: Date.now() - startedAt,
|
||||
});
|
||||
throw new Error("Timed out waiting for tus upload finalization");
|
||||
}
|
||||
|
||||
|
|
@ -153,6 +194,7 @@ export const useTusUpload = () => {
|
|||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [uploadError, setUploadError] = useState<Error | null>(null);
|
||||
const activeUploadRef = useRef<Upload | null>(null);
|
||||
const lastLoggedProgressRef = useRef(-10);
|
||||
|
||||
const mutation = useMutation<TusUploadResult, Error, TusUploadArgs>(
|
||||
["upload-file", "tus"],
|
||||
|
|
@ -161,15 +203,16 @@ export const useTusUpload = () => {
|
|||
throw new Error("File is required for tus upload");
|
||||
}
|
||||
|
||||
setIsUploading(true);
|
||||
setUploadProgress(0);
|
||||
setUploadError(null);
|
||||
let lastError: Error | null = null;
|
||||
|
||||
try {
|
||||
if (!TUS_ENDPOINT) {
|
||||
throw new Error("Tus endpoint is not configured");
|
||||
}
|
||||
|
||||
setIsUploading(true);
|
||||
setUploadProgress(0);
|
||||
setUploadError(null);
|
||||
|
||||
try {
|
||||
const result = await new Promise<TusUploadResult>((resolve, reject) => {
|
||||
const token = localStorage.getItem("auth_v1_token") ?? "";
|
||||
const normalizedMeta = normalizeMetadata(metadata);
|
||||
|
|
@ -178,6 +221,13 @@ export const useTusUpload = () => {
|
|||
headers.Authorization = token;
|
||||
}
|
||||
|
||||
console.info("[App2Client][TusUpload] Начинаем загрузку", {
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
metadata: normalizedMeta,
|
||||
});
|
||||
|
||||
const upload = new Upload(file, {
|
||||
endpoint: TUS_ENDPOINT,
|
||||
metadata: {
|
||||
|
|
@ -191,6 +241,7 @@ export const useTusUpload = () => {
|
|||
uploadDataDuringCreation: true,
|
||||
onError: (err) => {
|
||||
const normalized = normalizeError(err, "Tus upload failed");
|
||||
lastError = normalized;
|
||||
setUploadError(normalized);
|
||||
setIsUploading(false);
|
||||
setUploadProgress(0);
|
||||
|
|
@ -202,6 +253,16 @@ export const useTusUpload = () => {
|
|||
? Math.floor((bytesUploaded / bytesTotal) * 100)
|
||||
: 0;
|
||||
setUploadProgress(Math.min(99, Math.max(0, percent)));
|
||||
|
||||
if (percent >= lastLoggedProgressRef.current + 5 || percent === 100) {
|
||||
lastLoggedProgressRef.current = percent;
|
||||
console.info("[App2Client][TusUpload] Прогресс загрузки", {
|
||||
fileName: file.name,
|
||||
bytesUploaded,
|
||||
bytesTotal,
|
||||
percent,
|
||||
});
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
(async () => {
|
||||
|
|
@ -213,6 +274,10 @@ export const useTusUpload = () => {
|
|||
}
|
||||
|
||||
const uploadId = extractUploadId(uploadUrl);
|
||||
console.info("[App2Client][TusUpload] Загрузка завершена на tus, начинаем финализацию", {
|
||||
fileName: file.name,
|
||||
uploadId,
|
||||
});
|
||||
const status = await pollUploadStatus(uploadId, signal);
|
||||
const encryptedCid = status.encrypted_cid;
|
||||
if (!encryptedCid) {
|
||||
|
|
@ -223,6 +288,14 @@ export const useTusUpload = () => {
|
|||
setIsUploading(false);
|
||||
activeUploadRef.current = null;
|
||||
|
||||
console.info("[App2Client][TusUpload] Финализация tus завершена", {
|
||||
fileName: file.name,
|
||||
uploadId,
|
||||
encryptedCid,
|
||||
finalState: status.state,
|
||||
sizeBytes: status.size_bytes,
|
||||
});
|
||||
|
||||
resolve({
|
||||
kind: "tus",
|
||||
uploadId,
|
||||
|
|
@ -235,6 +308,11 @@ export const useTusUpload = () => {
|
|||
statusError,
|
||||
"Failed to finalize tus upload",
|
||||
);
|
||||
lastError = normalized;
|
||||
console.error("[App2Client][TusUpload] Ошибка финализации tus", {
|
||||
fileName: file.name,
|
||||
error: normalized,
|
||||
});
|
||||
setUploadError(normalized);
|
||||
setIsUploading(false);
|
||||
activeUploadRef.current = null;
|
||||
|
|
@ -245,6 +323,11 @@ export const useTusUpload = () => {
|
|||
});
|
||||
|
||||
activeUploadRef.current = upload;
|
||||
lastLoggedProgressRef.current = 0;
|
||||
|
||||
console.info("[App2Client][TusUpload] Запрашиваем предыдущие загрузки для возобновления", {
|
||||
fileName: file.name,
|
||||
});
|
||||
|
||||
if (signal) {
|
||||
signal.addEventListener(
|
||||
|
|
@ -255,6 +338,10 @@ export const useTusUpload = () => {
|
|||
"Tus upload aborted",
|
||||
"AbortError",
|
||||
);
|
||||
console.warn("[App2Client][TusUpload] Загрузка прервана внешним сигналом", {
|
||||
fileName: file.name,
|
||||
});
|
||||
lastError = abortError;
|
||||
setUploadError(abortError);
|
||||
setIsUploading(false);
|
||||
activeUploadRef.current = null;
|
||||
|
|
@ -267,16 +354,32 @@ export const useTusUpload = () => {
|
|||
upload
|
||||
.findPreviousUploads()
|
||||
.then((previousUploads) => {
|
||||
console.info("[App2Client][TusUpload] Результат поиска предыдущих загрузок", {
|
||||
fileName: file.name,
|
||||
count: previousUploads.length,
|
||||
});
|
||||
if (previousUploads.length > 0) {
|
||||
upload.resumeFromPreviousUpload(previousUploads[0]);
|
||||
console.info("[App2Client][TusUpload] Возобновляем загрузку", {
|
||||
fileName: file.name,
|
||||
});
|
||||
}
|
||||
upload.start();
|
||||
console.info("[App2Client][TusUpload] Стартуем загрузку", {
|
||||
fileName: file.name,
|
||||
chunkSize: upload.options.chunkSize,
|
||||
});
|
||||
})
|
||||
.catch((resumeError) => {
|
||||
const normalized = normalizeError(
|
||||
resumeError,
|
||||
"Failed to resume tus upload",
|
||||
);
|
||||
lastError = normalized;
|
||||
console.error("[App2Client][TusUpload] Не удалось возобновить загрузку", {
|
||||
fileName: file.name,
|
||||
error: normalized,
|
||||
});
|
||||
setUploadError(normalized);
|
||||
setIsUploading(false);
|
||||
activeUploadRef.current = null;
|
||||
|
|
@ -285,9 +388,25 @@ export const useTusUpload = () => {
|
|||
});
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
const normalized = normalizeError(error, "Tus upload failed");
|
||||
if (!lastError) {
|
||||
lastError = normalized;
|
||||
console.error("[App2Client][TusUpload] Ошибка во время загрузки", {
|
||||
fileName: file.name,
|
||||
error: normalized,
|
||||
});
|
||||
setUploadError(normalized);
|
||||
}
|
||||
setIsUploading(false);
|
||||
throw normalized;
|
||||
} finally {
|
||||
activeUploadRef.current = null;
|
||||
setIsUploading(false);
|
||||
console.info("[App2Client][TusUpload] Завершили работу загрузчика", {
|
||||
fileName: file?.name,
|
||||
hasError: Boolean(lastError),
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -300,6 +419,9 @@ export const useTusUpload = () => {
|
|||
activeUploadRef.current = null;
|
||||
setIsUploading(false);
|
||||
setUploadProgress(0);
|
||||
console.warn("[App2Client][TusUpload] Принудительно остановили загрузку", {
|
||||
reason: "manual",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -317,11 +439,21 @@ export const useLegacyUploadFile = () => {
|
|||
const [uploadProgress, setUploadProgress] = useState(0);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
const [uploadError, setUploadError] = useState<Error | null>(null);
|
||||
const lastLoggedProgressRef = useRef(-10);
|
||||
|
||||
const mutation = useMutation(["upload-file", "legacy"], async (file: File) => {
|
||||
setIsUploading(true);
|
||||
setUploadProgress(0);
|
||||
setUploadError(null);
|
||||
lastLoggedProgressRef.current = 0;
|
||||
let lastError: Error | null = null;
|
||||
|
||||
console.info("[App2Client][LegacyUpload] Начинаем загрузку", {
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
isChunked: file.size > MAX_CHUNK_SIZE,
|
||||
});
|
||||
|
||||
try {
|
||||
if (file.size <= MAX_CHUNK_SIZE) {
|
||||
|
|
@ -352,11 +484,35 @@ export const useLegacyUploadFile = () => {
|
|||
(progressEvent.loaded * 100) / total,
|
||||
);
|
||||
setUploadProgress(Math.min(99, percentCompleted));
|
||||
|
||||
if (
|
||||
percentCompleted >= lastLoggedProgressRef.current + 5 ||
|
||||
percentCompleted === 100
|
||||
) {
|
||||
lastLoggedProgressRef.current = percentCompleted;
|
||||
console.info("[App2Client][LegacyUpload] Прогресс загрузки", {
|
||||
fileName: file.name,
|
||||
percent: percentCompleted,
|
||||
loaded: progressEvent.loaded,
|
||||
total,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
setUploadProgress(100);
|
||||
|
||||
console.info("[App2Client][LegacyUpload] Загрузка завершена", {
|
||||
fileName: file.name,
|
||||
response: {
|
||||
hasContentId: Boolean(
|
||||
response.data.content_id_v1 || response.data.content_id,
|
||||
),
|
||||
hasSha256: Boolean(response.data.content_sha256),
|
||||
uploadId: response.data.upload_id,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
content_sha256: response.data.content_sha256 || "",
|
||||
content_id_v1:
|
||||
|
|
@ -392,6 +548,15 @@ export const useLegacyUploadFile = () => {
|
|||
headers["X-Upload-ID"] = uploadId;
|
||||
}
|
||||
|
||||
console.info("[App2Client][LegacyUpload] Отправляем chunk", {
|
||||
fileName: file.name,
|
||||
chunkStart: offset,
|
||||
chunkEnd,
|
||||
chunkSize: chunk.size,
|
||||
isLastChunk,
|
||||
uploadId,
|
||||
});
|
||||
|
||||
const response = await request.post<{
|
||||
upload_id?: string;
|
||||
current_size?: number;
|
||||
|
|
@ -408,16 +573,42 @@ export const useLegacyUploadFile = () => {
|
|||
(overallProgress / file.size) * 100,
|
||||
);
|
||||
setUploadProgress(Math.min(99, percentCompleted));
|
||||
|
||||
if (
|
||||
percentCompleted >= lastLoggedProgressRef.current + 5 ||
|
||||
percentCompleted === 100
|
||||
) {
|
||||
lastLoggedProgressRef.current = percentCompleted;
|
||||
console.info("[App2Client][LegacyUpload] Прогресс загрузки", {
|
||||
fileName: file.name,
|
||||
percent: percentCompleted,
|
||||
loaded: overallProgress,
|
||||
total: file.size,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!uploadId && response.data.upload_id) {
|
||||
uploadId = response.data.upload_id;
|
||||
console.info("[App2Client][LegacyUpload] Получили upload_id", {
|
||||
fileName: file.name,
|
||||
uploadId,
|
||||
});
|
||||
}
|
||||
|
||||
if (response.data.content_id) {
|
||||
setUploadProgress(100);
|
||||
|
||||
console.info("[App2Client][LegacyUpload] Сервер вернул итоговые данные", {
|
||||
fileName: file.name,
|
||||
uploadId,
|
||||
hasContentId: Boolean(
|
||||
response.data.content_id_v1 || response.data.content_id,
|
||||
),
|
||||
hasSha256: Boolean(response.data.content_sha256),
|
||||
});
|
||||
|
||||
return {
|
||||
content_sha256: response.data.content_sha256 || "",
|
||||
content_id_v1:
|
||||
|
|
@ -428,9 +619,18 @@ export const useLegacyUploadFile = () => {
|
|||
|
||||
if (response.data.current_size !== undefined) {
|
||||
offset = response.data.current_size;
|
||||
console.info("[App2Client][LegacyUpload] Продолжаем загрузку", {
|
||||
fileName: file.name,
|
||||
nextOffset: offset,
|
||||
});
|
||||
} else {
|
||||
const error = new Error("Missing current_size in response");
|
||||
setUploadError(error);
|
||||
lastError = error;
|
||||
console.error("[App2Client][LegacyUpload] Сервер не вернул current_size", {
|
||||
fileName: file.name,
|
||||
response,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -439,6 +639,10 @@ export const useLegacyUploadFile = () => {
|
|||
"All chunks uploaded but server did not return content_id",
|
||||
);
|
||||
setUploadError(error);
|
||||
lastError = error;
|
||||
console.error("[App2Client][LegacyUpload] Все чанки отправлены, но content_id отсутствует", {
|
||||
fileName: file.name,
|
||||
});
|
||||
throw error;
|
||||
} catch (error) {
|
||||
const normalized = normalizeError(
|
||||
|
|
@ -447,9 +651,18 @@ export const useLegacyUploadFile = () => {
|
|||
);
|
||||
setUploadError(normalized);
|
||||
setIsUploading(false);
|
||||
lastError = normalized;
|
||||
console.error("[App2Client][LegacyUpload] Ошибка во время загрузки", {
|
||||
fileName: file.name,
|
||||
error: normalized,
|
||||
});
|
||||
throw normalized;
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
console.info("[App2Client][LegacyUpload] Завершили работу загрузчика", {
|
||||
fileName: file.name,
|
||||
hasError: Boolean(lastError),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue