@@ -7,6 +7,17 @@ export interface MatrixAuth {
77
88export type RealmTokens = Record < string , string > ;
99
10+ // Thrown when Matrix rejects an access token (401/403). Callers can catch
11+ // this specifically to drive interactive re-auth without parsing messages.
12+ export class MatrixAuthError extends Error {
13+ status : number ;
14+ constructor ( status : number , message : string ) {
15+ super ( message ) ;
16+ this . name = 'MatrixAuthError' ;
17+ this . status = status ;
18+ }
19+ }
20+
1021interface MatrixLoginResponse {
1122 access_token : string ;
1223 device_id : string ;
@@ -69,6 +80,12 @@ async function getOpenIdToken(
6980
7081 if ( ! response . ok ) {
7182 let text = await response . text ( ) ;
83+ if ( response . status === 401 || response . status === 403 ) {
84+ throw new MatrixAuthError (
85+ response . status ,
86+ `OpenID token request failed: ${ response . status } ${ text } ` ,
87+ ) ;
88+ }
7289 throw new Error ( `OpenID token request failed: ${ response . status } ${ text } ` ) ;
7390 }
7491
@@ -138,17 +155,30 @@ function userRealmsAccountDataUrl(matrixAuth: MatrixAuth): string {
138155export async function getUserRealmsFromMatrixAccountData (
139156 matrixAuth : MatrixAuth ,
140157) : Promise < string [ ] > {
158+ let response : Response ;
141159 try {
142- let response = await fetch ( userRealmsAccountDataUrl ( matrixAuth ) , {
160+ response = await fetch ( userRealmsAccountDataUrl ( matrixAuth ) , {
143161 headers : { Authorization : `Bearer ${ matrixAuth . accessToken } ` } ,
144162 } ) ;
145- if ( ! response . ok ) {
146- return [ ] ;
147- }
163+ } catch {
164+ // Network unreachable / DNS / similar — treat as empty (best-effort).
165+ return [ ] ;
166+ }
167+ if ( response . status === 401 || response . status === 403 ) {
168+ let text = await response . text ( ) ;
169+ throw new MatrixAuthError (
170+ response . status ,
171+ `Matrix account_data fetch failed: ${ response . status } ${ text } ` ,
172+ ) ;
173+ }
174+ if ( ! response . ok ) {
175+ // 404 just means the event has never been set — return empty list.
176+ return [ ] ;
177+ }
178+ try {
148179 let data = ( await response . json ( ) ) as { realms ?: string [ ] } ;
149180 return Array . isArray ( data . realms ) ? [ ...data . realms ] : [ ] ;
150181 } catch {
151- // Best-effort — treat unreachable account data as an empty list
152182 return [ ] ;
153183 }
154184}
@@ -171,6 +201,12 @@ export async function addRealmToMatrixAccountData(
171201 } ) ;
172202 if ( ! putResponse . ok ) {
173203 let text = await putResponse . text ( ) ;
204+ if ( putResponse . status === 401 || putResponse . status === 403 ) {
205+ throw new MatrixAuthError (
206+ putResponse . status ,
207+ `Failed to update Matrix account data: ${ putResponse . status } ${ text } ` ,
208+ ) ;
209+ }
174210 throw new Error (
175211 `Failed to update Matrix account data: ${ putResponse . status } ${ text } ` ,
176212 ) ;
@@ -205,6 +241,12 @@ export async function removeRealmFromMatrixAccountData(
205241 } ) ;
206242 if ( ! putResponse . ok ) {
207243 let text = await putResponse . text ( ) ;
244+ if ( putResponse . status === 401 || putResponse . status === 403 ) {
245+ throw new MatrixAuthError (
246+ putResponse . status ,
247+ `Failed to update Matrix account data: ${ putResponse . status } ${ text } ` ,
248+ ) ;
249+ }
208250 throw new Error (
209251 `Failed to update Matrix account data: ${ putResponse . status } ${ text } ` ,
210252 ) ;
0 commit comments