You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
Make sure that MegolmEncryption.setupPromise always resolves (#2960)
ensureOutboundSession uses and modifies the setupPromise of the
MegolmEncryption class. Some comments suggest that setupPromise will
always resolve, in other words it should never contain a promise that
will get rejected.
Other comments also seem to suggest that the return value of
ensureOutboundSession, a promise as well, may fail.
The critical error here is that the promise that gets set as
the next setupPromise, as well as the promise that ensureOutboundSession
returns, is the same promise.
It seems that the intention was for setupPromise to contain a promise
that will always resolve to either `null` or `OutboundSessionInfo`.
We can see that a couple of lines before we set setupPromise to its new
value we construct a promise that logs and discards errors using the
`Promise.catch()` method.
The `Promise.catch()` method does not mutate the promise, instead it
returns a new promise. The intention of the original author might have
been to set the next setupPromise to the promise which `Promise.catch()`
produces.
This patch modifies the updating of setupPromise in the
ensureOutboundSession so that setupPromise discards errors correctly.
Using `>>=` to represent the promise chaining operation, setupPromise is
now updated using the following logic:
setupPromise = previousSetupPromise >>= setup >>= discardErrors
This commit is contained in:
@@ -490,6 +490,26 @@ describe("MegolmDecryption", function () {
|
||||
|
||||
expect(mockBaseApis.queueToDevice).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shouldn't wedge the setup promise if sharing a room key fails", async () => {
|
||||
// @ts-ignore - private field access
|
||||
const initialSetupPromise = await megolmEncryption.setupPromise;
|
||||
expect(initialSetupPromise).toBe(null);
|
||||
|
||||
// @ts-ignore - private field access
|
||||
megolmEncryption.prepareSession = () => {
|
||||
throw new Error("Can't prepare session");
|
||||
};
|
||||
|
||||
await expect(() =>
|
||||
// @ts-ignore - private field access
|
||||
megolmEncryption.ensureOutboundSession(mockRoom, {}, {}, true),
|
||||
).rejects.toThrow();
|
||||
|
||||
// @ts-ignore - private field access
|
||||
const finalSetupPromise = await megolmEncryption.setupPromise;
|
||||
expect(finalSetupPromise).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user