-
-
Notifications
You must be signed in to change notification settings - Fork 833
Properly translate errors in AddThreepid.ts
so they show up translated to the user but not in our logs
#10432
Changes from all commits
72c08a1
777a4fc
167150d
4492ecc
8c24afb
e57a11c
ebbb455
b3d37fb
cf0ba20
e557019
e6f053a
8152c6b
d88d5f2
6e21c16
078e24b
924416c
1cd8ec0
306a1dc
ac02179
8675464
529212c
edac565
477db79
629f429
c2080ce
8ffeb6f
1b54ba6
96ba896
f8164d3
016341a
5d74ef9
ac67f1f
251df4d
ae8bdaf
817190c
ed00c59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,20 +17,21 @@ limitations under the License. | |
*/ | ||
|
||
import { IAuthData, IRequestMsisdnTokenResponse, IRequestTokenResponse } from "matrix-js-sdk/src/matrix"; | ||
import { MatrixError, HTTPError } from "matrix-js-sdk/src/matrix"; | ||
|
||
import { MatrixClientPeg } from "./MatrixClientPeg"; | ||
import Modal from "./Modal"; | ||
import { _t } from "./languageHandler"; | ||
import { _t, UserFriendlyError } from "./languageHandler"; | ||
import IdentityAuthClient from "./IdentityAuthClient"; | ||
import { SSOAuthEntry } from "./components/views/auth/InteractiveAuthEntryComponents"; | ||
import InteractiveAuthDialog from "./components/views/dialogs/InteractiveAuthDialog"; | ||
|
||
function getIdServerDomain(): string { | ||
const idBaseUrl = MatrixClientPeg.get().idBaseUrl; | ||
const idBaseUrl = MatrixClientPeg.get().getIdentityServerUrl(true); | ||
if (!idBaseUrl) { | ||
throw new Error("Identity server not set"); | ||
throw new UserFriendlyError("Identity server not set"); | ||
} | ||
return idBaseUrl.split("://")[1]; | ||
return idBaseUrl; | ||
} | ||
|
||
export type Binding = { | ||
|
@@ -67,23 +68,18 @@ export default class AddThreepid { | |
* @param {string} emailAddress The email address to add | ||
* @return {Promise} Resolves when the email has been sent. Then call checkEmailLinkClicked(). | ||
*/ | ||
public addEmailAddress(emailAddress: string): Promise<IRequestTokenResponse> { | ||
return MatrixClientPeg.get() | ||
.requestAdd3pidEmailToken(emailAddress, this.clientSecret, 1) | ||
.then( | ||
(res) => { | ||
this.sessionId = res.sid; | ||
return res; | ||
}, | ||
function (err) { | ||
if (err.errcode === "M_THREEPID_IN_USE") { | ||
err.message = _t("This email address is already in use"); | ||
} else if (err.httpStatus) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bit of logging seems to get lost, is that intended? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, see #10432 (comment)
|
||
err.message = err.message + ` (Status ${err.httpStatus})`; | ||
} | ||
throw err; | ||
}, | ||
); | ||
public async addEmailAddress(emailAddress: string): Promise<IRequestTokenResponse> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are just getting some |
||
try { | ||
const res = await MatrixClientPeg.get().requestAdd3pidEmailToken(emailAddress, this.clientSecret, 1); | ||
this.sessionId = res.sid; | ||
return res; | ||
} catch (err) { | ||
if (err instanceof MatrixError && err.errcode === "M_THREEPID_IN_USE") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the nature of unifying our error handling, we're going to have "duplicate lines" that SonarCloud is calling out. Need an exception here. I've already de-duplicated some logic with |
||
throw new UserFriendlyError("This email address is already in use", { cause: err }); | ||
} | ||
// Otherwise, just blurt out the same error | ||
throw err; | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -98,22 +94,23 @@ export default class AddThreepid { | |
// For separate bind, request a token directly from the IS. | ||
const authClient = new IdentityAuthClient(); | ||
const identityAccessToken = (await authClient.getAccessToken()) ?? undefined; | ||
return MatrixClientPeg.get() | ||
.requestEmailToken(emailAddress, this.clientSecret, 1, undefined, identityAccessToken) | ||
.then( | ||
(res) => { | ||
this.sessionId = res.sid; | ||
return res; | ||
}, | ||
function (err) { | ||
if (err.errcode === "M_THREEPID_IN_USE") { | ||
err.message = _t("This email address is already in use"); | ||
} else if (err.httpStatus) { | ||
err.message = err.message + ` (Status ${err.httpStatus})`; | ||
} | ||
throw err; | ||
}, | ||
try { | ||
const res = await MatrixClientPeg.get().requestEmailToken( | ||
emailAddress, | ||
this.clientSecret, | ||
1, | ||
undefined, | ||
identityAccessToken, | ||
); | ||
this.sessionId = res.sid; | ||
return res; | ||
} catch (err) { | ||
if (err instanceof MatrixError && err.errcode === "M_THREEPID_IN_USE") { | ||
throw new UserFriendlyError("This email address is already in use", { cause: err }); | ||
} | ||
// Otherwise, just blurt out the same error | ||
throw err; | ||
} | ||
} else { | ||
// For tangled bind, request a token via the HS. | ||
return this.addEmailAddress(emailAddress); | ||
|
@@ -127,24 +124,24 @@ export default class AddThreepid { | |
* @param {string} phoneNumber The national or international formatted phone number to add | ||
* @return {Promise} Resolves when the text message has been sent. Then call haveMsisdnToken(). | ||
*/ | ||
public addMsisdn(phoneCountry: string, phoneNumber: string): Promise<IRequestMsisdnTokenResponse> { | ||
return MatrixClientPeg.get() | ||
.requestAdd3pidMsisdnToken(phoneCountry, phoneNumber, this.clientSecret, 1) | ||
.then( | ||
(res) => { | ||
this.sessionId = res.sid; | ||
this.submitUrl = res.submit_url; | ||
return res; | ||
}, | ||
function (err) { | ||
if (err.errcode === "M_THREEPID_IN_USE") { | ||
err.message = _t("This phone number is already in use"); | ||
} else if (err.httpStatus) { | ||
err.message = err.message + ` (Status ${err.httpStatus})`; | ||
} | ||
throw err; | ||
}, | ||
public async addMsisdn(phoneCountry: string, phoneNumber: string): Promise<IRequestMsisdnTokenResponse> { | ||
try { | ||
const res = await MatrixClientPeg.get().requestAdd3pidMsisdnToken( | ||
phoneCountry, | ||
phoneNumber, | ||
this.clientSecret, | ||
1, | ||
); | ||
this.sessionId = res.sid; | ||
this.submitUrl = res.submit_url; | ||
return res; | ||
} catch (err) { | ||
if (err instanceof MatrixError && err.errcode === "M_THREEPID_IN_USE") { | ||
throw new UserFriendlyError("This phone number is already in use", { cause: err }); | ||
} | ||
// Otherwise, just blurt out the same error | ||
throw err; | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -160,22 +157,24 @@ export default class AddThreepid { | |
// For separate bind, request a token directly from the IS. | ||
const authClient = new IdentityAuthClient(); | ||
const identityAccessToken = (await authClient.getAccessToken()) ?? undefined; | ||
return MatrixClientPeg.get() | ||
.requestMsisdnToken(phoneCountry, phoneNumber, this.clientSecret, 1, undefined, identityAccessToken) | ||
.then( | ||
(res) => { | ||
this.sessionId = res.sid; | ||
return res; | ||
}, | ||
function (err) { | ||
if (err.errcode === "M_THREEPID_IN_USE") { | ||
err.message = _t("This phone number is already in use"); | ||
} else if (err.httpStatus) { | ||
err.message = err.message + ` (Status ${err.httpStatus})`; | ||
} | ||
throw err; | ||
}, | ||
try { | ||
const res = await MatrixClientPeg.get().requestMsisdnToken( | ||
phoneCountry, | ||
phoneNumber, | ||
this.clientSecret, | ||
1, | ||
undefined, | ||
identityAccessToken, | ||
); | ||
this.sessionId = res.sid; | ||
return res; | ||
} catch (err) { | ||
if (err instanceof MatrixError && err.errcode === "M_THREEPID_IN_USE") { | ||
throw new UserFriendlyError("This phone number is already in use", { cause: err }); | ||
} | ||
// Otherwise, just blurt out the same error | ||
throw err; | ||
} | ||
} else { | ||
// For tangled bind, request a token via the HS. | ||
return this.addMsisdn(phoneCountry, phoneNumber); | ||
|
@@ -195,7 +194,7 @@ export default class AddThreepid { | |
const authClient = new IdentityAuthClient(); | ||
const identityAccessToken = await authClient.getAccessToken(); | ||
if (!identityAccessToken) { | ||
throw new Error("No identity access token found"); | ||
throw new UserFriendlyError("No identity access token found"); | ||
} | ||
await MatrixClientPeg.get().bindThreePid({ | ||
sid: this.sessionId, | ||
|
@@ -210,10 +209,10 @@ export default class AddThreepid { | |
// The spec has always required this to use UI auth but synapse briefly | ||
// implemented it without, so this may just succeed and that's OK. | ||
return [true]; | ||
} catch (e) { | ||
if (e.httpStatus !== 401 || !e.data || !e.data.flows) { | ||
} catch (err) { | ||
if (!(err instanceof MatrixError) || err.httpStatus !== 401 || !err.data || !err.data.flows) { | ||
// doesn't look like an interactive-auth failure | ||
throw e; | ||
throw err; | ||
} | ||
|
||
const dialogAesthetics = { | ||
|
@@ -235,7 +234,7 @@ export default class AddThreepid { | |
const { finished } = Modal.createDialog(InteractiveAuthDialog, { | ||
title: _t("Add Email Address"), | ||
matrixClient: MatrixClientPeg.get(), | ||
authData: e.data, | ||
authData: err.data, | ||
makeRequest: this.makeAddThreepidOnlyRequest, | ||
aestheticsForStagePhases: { | ||
[SSOAuthEntry.LOGIN_TYPE]: dialogAesthetics, | ||
|
@@ -256,11 +255,13 @@ export default class AddThreepid { | |
); | ||
} | ||
} catch (err) { | ||
if (err.httpStatus === 401) { | ||
err.message = _t("Failed to verify email address: make sure you clicked the link in the email"); | ||
} else if (err.httpStatus) { | ||
err.message += ` (Status ${err.httpStatus})`; | ||
if (err instanceof HTTPError && err.httpStatus === 401) { | ||
throw new UserFriendlyError( | ||
"Failed to verify email address: make sure you clicked the link in the email", | ||
{ cause: err }, | ||
); | ||
} | ||
// Otherwise, just blurt out the same error | ||
throw err; | ||
} | ||
return []; | ||
|
@@ -308,7 +309,7 @@ export default class AddThreepid { | |
await authClient.getAccessToken(), | ||
); | ||
} else { | ||
throw new Error("The add / bind with MSISDN flow is misconfigured"); | ||
throw new UserFriendlyError("The add / bind with MSISDN flow is misconfigured"); | ||
} | ||
if (result.errcode) { | ||
throw result; | ||
|
@@ -329,10 +330,10 @@ export default class AddThreepid { | |
// The spec has always required this to use UI auth but synapse briefly | ||
// implemented it without, so this may just succeed and that's OK. | ||
return; | ||
} catch (e) { | ||
if (e.httpStatus !== 401 || !e.data || !e.data.flows) { | ||
} catch (err) { | ||
if (!(err instanceof MatrixError) || err.httpStatus !== 401 || !err.data || !err.data.flows) { | ||
// doesn't look like an interactive-auth failure | ||
throw e; | ||
throw err; | ||
} | ||
|
||
const dialogAesthetics = { | ||
|
@@ -354,7 +355,7 @@ export default class AddThreepid { | |
const { finished } = Modal.createDialog(InteractiveAuthDialog, { | ||
title: _t("Add Phone Number"), | ||
matrixClient: MatrixClientPeg.get(), | ||
authData: e.data, | ||
authData: err.data, | ||
makeRequest: this.makeAddThreepidOnlyRequest, | ||
aestheticsForStagePhases: { | ||
[SSOAuthEntry.LOGIN_TYPE]: dialogAesthetics, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining strict TypeScript lints are tracked by element-hq/element-web#24899