Skip to content

Commit 0711c27

Browse files
committed
Add support for experimental MSC4335 M_USER_EXCEEDED_LIMIT error code
1 parent 3142af2 commit 0711c27

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

src/ContentMessages.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
type UploadOpts,
1919
type UploadProgress,
2020
THREAD_RELATION_TYPE,
21+
MatrixError,
2122
} from "matrix-js-sdk/src/matrix";
2223
import {
2324
type ImageInfo,
@@ -31,6 +32,7 @@ import encrypt from "matrix-encrypt-attachment";
3132
import extractPngChunks from "png-chunks-extract";
3233
import { logger } from "matrix-js-sdk/src/logger";
3334
import { removeElement } from "matrix-js-sdk/src/utils";
35+
import React, { type ReactNode } from "react";
3436

3537
import dis from "./dispatcher/dispatcher";
3638
import { _t } from "./languageHandler";
@@ -653,12 +655,36 @@ export default class ContentMessages {
653655
}
654656

655657
if (!upload.cancelled) {
656-
let desc = _t("upload_failed_generic", { fileName: upload.fileName });
658+
let desc: ReactNode = _t("upload_failed_generic", { fileName: upload.fileName });
657659
if (unwrappedError instanceof HTTPError && unwrappedError.httpStatus === 413) {
658660
desc = _t("upload_failed_size", {
659661
fileName: upload.fileName,
660662
});
663+
} else if (
664+
unwrappedError instanceof MatrixError &&
665+
unwrappedError.errcode === "M_UNKNOWN" &&
666+
unwrappedError.data["org.matrix.msc4335.errcode"] === "M_USER_LIMIT_EXCEEDED" &&
667+
typeof unwrappedError.data["org.matrix.msc4335.info_url"] === "string"
668+
) {
669+
// Support for experimental MSC4335 M_USER_LIMIT_EXCEEDED error
670+
desc = _t(
671+
"msc4335_upload_failed_user_limit_exceeded",
672+
{ fileName: upload.fileName },
673+
{
674+
a: (sub): ReactNode =>
675+
React.createElement(
676+
"a",
677+
{
678+
target: "_blank",
679+
href: unwrappedError.data["org.matrix.msc4335.info_url"],
680+
rel: "noreferrer noopener",
681+
},
682+
sub,
683+
),
684+
},
685+
);
661686
}
687+
662688
Modal.createDialog(ErrorDialog, {
663689
title: _t("upload_failed_title"),
664690
description: desc,

src/i18n/strings/en_EN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3872,6 +3872,7 @@
38723872
"title": "Allow guest users to join this room"
38733873
},
38743874
"upload_failed_generic": "The file '%(fileName)s' failed to upload.",
3875+
"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>",
38753876
"upload_failed_size": "The file '%(fileName)s' exceeds this homeserver's size limit for uploads",
38763877
"upload_failed_title": "Upload Failed",
38773878
"upload_file": {

test/unit-tests/ContentMessages-test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from "matrix-js-sdk/src/matrix";
1717
import { type ImageInfo } from "matrix-js-sdk/src/types";
1818
import encrypt, { type IEncryptedFile } from "matrix-encrypt-attachment";
19+
import { render } from "jest-matrix-react";
1920

2021
import ContentMessages, { UploadCanceledError, uploadFile } from "../../src/ContentMessages";
2122
import { doMaybeLocalRoomAction } from "../../src/utils/local-room";
@@ -317,6 +318,24 @@ describe("ContentMessages", () => {
317318
);
318319
dialogSpy.mockRestore();
319320
});
321+
322+
it("handles MSC4335 M_USER_LIMIT_EXCEEDED error and shows info URL", async () => {
323+
mocked(client.uploadContent).mockRejectedValue(
324+
new MatrixError({
325+
"errcode": "M_UNKNOWN",
326+
"error": "User limit exceeded",
327+
"org.matrix.msc4335.errcode": "M_USER_LIMIT_EXCEEDED",
328+
"org.matrix.msc4335.info_url": "https://example.com/info",
329+
}),
330+
);
331+
const file = new File([], "fileName", { type: "image/jpeg" });
332+
const dialogSpy = jest.spyOn(Modal, "createDialog");
333+
await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined);
334+
const { container } = render(dialogSpy.mock.calls[0][1]?.description);
335+
const link = container.querySelector('a[href="https://example.com/info"]');
336+
expect(link).toBeTruthy();
337+
dialogSpy.mockRestore();
338+
});
320339
});
321340

322341
describe("getCurrentUploads", () => {

0 commit comments

Comments
 (0)