Compare commits

...

1 Commits

Author SHA1 Message Date
Hugh Nimmo-Smith
7a48a0ddc6 Add support for experimental MSC4335 M_USER_EXCEEDED_LIMIT error code 2025-09-12 12:08:28 +01:00
3 changed files with 47 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ import {
type UploadOpts,
type UploadProgress,
THREAD_RELATION_TYPE,
MatrixError,
} from "matrix-js-sdk/src/matrix";
import {
type ImageInfo,
@@ -31,6 +32,7 @@ import encrypt from "matrix-encrypt-attachment";
import extractPngChunks from "png-chunks-extract";
import { logger } from "matrix-js-sdk/src/logger";
import { removeElement } from "matrix-js-sdk/src/utils";
import React, { type ReactNode } from "react";
import dis from "./dispatcher/dispatcher";
import { _t } from "./languageHandler";
@@ -653,12 +655,36 @@ export default class ContentMessages {
}
if (!upload.cancelled) {
let desc = _t("upload_failed_generic", { fileName: upload.fileName });
let desc: ReactNode = _t("upload_failed_generic", { fileName: upload.fileName });
if (unwrappedError instanceof HTTPError && unwrappedError.httpStatus === 413) {
desc = _t("upload_failed_size", {
fileName: upload.fileName,
});
} else if (
unwrappedError instanceof MatrixError &&
unwrappedError.errcode === "M_UNKNOWN" &&
unwrappedError.data["org.matrix.msc4335.errcode"] === "M_USER_LIMIT_EXCEEDED" &&
typeof unwrappedError.data["org.matrix.msc4335.info_url"] === "string"
) {
// Support for experimental MSC4335 M_USER_LIMIT_EXCEEDED error
desc = _t(
"msc4335_upload_failed_user_limit_exceeded",
{ fileName: upload.fileName },
{
a: (sub): ReactNode =>
React.createElement(
"a",
{
target: "_blank",
href: unwrappedError.data["org.matrix.msc4335.info_url"],
rel: "noreferrer noopener",
},
sub,
),
},
);
}
Modal.createDialog(ErrorDialog, {
title: _t("upload_failed_title"),
description: desc,

View File

@@ -1676,6 +1676,7 @@
"toast_description": "%(brand)s is experimental on a mobile web browser. For a better experience and the latest features, use our free native app.",
"toast_title": "Use app for a better experience"
},
"msc4335_upload_failed_user_limit_exceeded": "The file '%(fileName)s' failed to upload due to exceeding a limit on your account. <a>Information about your account limits</a>",
"name_and_id": "%(name)s (%(userId)s)",
"no_more_results": "No more results",
"notif_panel": {

View File

@@ -16,6 +16,7 @@ import {
} from "matrix-js-sdk/src/matrix";
import { type ImageInfo } from "matrix-js-sdk/src/types";
import encrypt, { type IEncryptedFile } from "matrix-encrypt-attachment";
import { render } from "jest-matrix-react";
import ContentMessages, { UploadCanceledError, uploadFile } from "../../src/ContentMessages";
import { doMaybeLocalRoomAction } from "../../src/utils/local-room";
@@ -317,6 +318,24 @@ describe("ContentMessages", () => {
);
dialogSpy.mockRestore();
});
it("handles MSC4335 M_USER_LIMIT_EXCEEDED error and shows info URL", async () => {
mocked(client.uploadContent).mockRejectedValue(
new MatrixError({
"errcode": "M_UNKNOWN",
"error": "User limit exceeded",
"org.matrix.msc4335.errcode": "M_USER_LIMIT_EXCEEDED",
"org.matrix.msc4335.info_url": "https://example.com/info",
}),
);
const file = new File([], "fileName", { type: "image/jpeg" });
const dialogSpy = jest.spyOn(Modal, "createDialog");
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
const { container } = render(dialogSpy.mock.calls[0][1]?.description);
const link = container.querySelector('a[href="https://example.com/info"]');
expect(link).toBeTruthy();
dialogSpy.mockRestore();
});
});
describe("getCurrentUploads", () => {