mirror of
https://github.com/element-hq/element-web.git
synced 2025-09-17 11:04:05 +02:00
Fix handling of 413 server response when uploading media (#30737)
This commit is contained in:
@@ -63,7 +63,12 @@ import { blobIsAnimated } from "./utils/Image.ts";
|
|||||||
const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01];
|
const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01];
|
||||||
|
|
||||||
export class UploadCanceledError extends Error {}
|
export class UploadCanceledError extends Error {}
|
||||||
export class UploadFailedError extends Error {}
|
export class UploadFailedError extends Error {
|
||||||
|
public constructor(cause: any) {
|
||||||
|
super();
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface IMediaConfig {
|
interface IMediaConfig {
|
||||||
"m.upload.size"?: number;
|
"m.upload.size"?: number;
|
||||||
@@ -367,7 +372,7 @@ export async function uploadFile(
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (abortController.signal.aborted) throw new UploadCanceledError();
|
if (abortController.signal.aborted) throw new UploadCanceledError();
|
||||||
console.error("Failed to upload file", e);
|
console.error("Failed to upload file", e);
|
||||||
throw new UploadFailedError();
|
throw new UploadFailedError(e);
|
||||||
}
|
}
|
||||||
if (abortController.signal.aborted) throw new UploadCanceledError();
|
if (abortController.signal.aborted) throw new UploadCanceledError();
|
||||||
|
|
||||||
@@ -386,7 +391,7 @@ export async function uploadFile(
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (abortController.signal.aborted) throw new UploadCanceledError();
|
if (abortController.signal.aborted) throw new UploadCanceledError();
|
||||||
console.error("Failed to upload file", e);
|
console.error("Failed to upload file", e);
|
||||||
throw new UploadFailedError();
|
throw new UploadFailedError(e);
|
||||||
}
|
}
|
||||||
if (abortController.signal.aborted) throw new UploadCanceledError();
|
if (abortController.signal.aborted) throw new UploadCanceledError();
|
||||||
// If the attachment isn't encrypted then include the URL directly.
|
// If the attachment isn't encrypted then include the URL directly.
|
||||||
@@ -638,15 +643,18 @@ export default class ContentMessages {
|
|||||||
dis.dispatch<UploadFinishedPayload>({ action: Action.UploadFinished, upload });
|
dis.dispatch<UploadFinishedPayload>({ action: Action.UploadFinished, upload });
|
||||||
dis.dispatch({ action: "message_sent" });
|
dis.dispatch({ action: "message_sent" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// Unwrap UploadFailedError to get the underlying error
|
||||||
|
const unwrappedError = error instanceof UploadFailedError && error.cause ? error.cause : error;
|
||||||
|
|
||||||
// 413: File was too big or upset the server in some way:
|
// 413: File was too big or upset the server in some way:
|
||||||
// clear the media size limit so we fetch it again next time we try to upload
|
// clear the media size limit so we fetch it again next time we try to upload
|
||||||
if (error instanceof HTTPError && error.httpStatus === 413) {
|
if (unwrappedError instanceof HTTPError && unwrappedError.httpStatus === 413) {
|
||||||
this.mediaConfig = null;
|
this.mediaConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!upload.cancelled) {
|
if (!upload.cancelled) {
|
||||||
let desc = _t("upload_failed_generic", { fileName: upload.fileName });
|
let desc = _t("upload_failed_generic", { fileName: upload.fileName });
|
||||||
if (error instanceof HTTPError && error.httpStatus === 413) {
|
if (unwrappedError instanceof HTTPError && unwrappedError.httpStatus === 413) {
|
||||||
desc = _t("upload_failed_size", {
|
desc = _t("upload_failed_size", {
|
||||||
fileName: upload.fileName,
|
fileName: upload.fileName,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { mocked } from "jest-mock";
|
|||||||
import {
|
import {
|
||||||
type ISendEventResponse,
|
type ISendEventResponse,
|
||||||
type MatrixClient,
|
type MatrixClient,
|
||||||
|
MatrixError,
|
||||||
RelationType,
|
RelationType,
|
||||||
type UploadResponse,
|
type UploadResponse,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
@@ -20,6 +21,9 @@ import ContentMessages, { UploadCanceledError, uploadFile } from "../../src/Cont
|
|||||||
import { doMaybeLocalRoomAction } from "../../src/utils/local-room";
|
import { doMaybeLocalRoomAction } from "../../src/utils/local-room";
|
||||||
import { createTestClient, flushPromises, mkEvent } from "../test-utils";
|
import { createTestClient, flushPromises, mkEvent } from "../test-utils";
|
||||||
import { BlurhashEncoder } from "../../src/BlurhashEncoder";
|
import { BlurhashEncoder } from "../../src/BlurhashEncoder";
|
||||||
|
import Modal from "../../src/Modal";
|
||||||
|
import ErrorDialog from "../../src/components/views/dialogs/ErrorDialog";
|
||||||
|
import { _t } from "../../src/languageHandler";
|
||||||
|
|
||||||
jest.mock("matrix-encrypt-attachment", () => ({ encryptAttachment: jest.fn().mockResolvedValue({}) }));
|
jest.mock("matrix-encrypt-attachment", () => ({ encryptAttachment: jest.fn().mockResolvedValue({}) }));
|
||||||
|
|
||||||
@@ -291,6 +295,28 @@ describe("ContentMessages", () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("handles 413 error", async () => {
|
||||||
|
mocked(client.uploadContent).mockRejectedValue(
|
||||||
|
new MatrixError(
|
||||||
|
{
|
||||||
|
errcode: "M_TOO_LARGE",
|
||||||
|
error: "File size limit exceeded",
|
||||||
|
},
|
||||||
|
413,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const file = new File([], "fileName", { type: "image/jpeg" });
|
||||||
|
const dialogSpy = jest.spyOn(Modal, "createDialog");
|
||||||
|
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
|
||||||
|
expect(dialogSpy).toHaveBeenCalledWith(
|
||||||
|
ErrorDialog,
|
||||||
|
expect.objectContaining({
|
||||||
|
description: _t("upload_failed_size", { fileName: "fileName" }),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
dialogSpy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getCurrentUploads", () => {
|
describe("getCurrentUploads", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user