@@ -44,6 +44,7 @@ export async function deleteDocument(collectionName: string, resource: SelectedR
4444import { DbInfo , CollectionInfo , CosmosDBAccount , SelectedResource , PaginatedDocumentsResponse , FoundDocumentResponse , DocumentHistoryResponse } from '../types' ;
4545import { msalInstance , loginRequest } from '../authConfig' ;
4646import { USE_MSAL_AUTH , API_BASE_URL } from '../app.config' ;
47+ import { getAuthErrorMessage , isAuthenticationExpiredError } from '../utils/authErrorHandler' ;
4748import {
4849 mockCosmosAccounts ,
4950 mockDatabasesByAccountId ,
@@ -60,6 +61,32 @@ import {
6061 mockUpdateDocument
6162} from './mockData' ;
6263
64+ /**
65+ * Helper function to get access token with proper error handling
66+ */
67+ const getAuthenticatedToken = async ( ) : Promise < string > => {
68+ try {
69+ const accounts = msalInstance . getAllAccounts ( ) ;
70+ if ( accounts . length === 0 ) {
71+ throw new Error ( "No signed-in user found." ) ;
72+ }
73+
74+ const response = await msalInstance . acquireTokenSilent ( {
75+ ...loginRequest ,
76+ account : accounts [ 0 ] ,
77+ } ) ;
78+
79+ return response . accessToken ;
80+ } catch ( error ) {
81+ // Handle authentication errors with user-friendly messages
82+ if ( isAuthenticationExpiredError ( error ) ) {
83+ throw new Error ( getAuthErrorMessage ( error ) ) ;
84+ }
85+ // Re-throw other errors as-is
86+ throw error ;
87+ }
88+ } ;
89+
6390/**
6491 * Fetches available Azure Cosmos DB resources from the backend.
6592 * @returns A promise that resolves with an array of Cosmos DB resources.
@@ -73,34 +100,43 @@ export const getAzureCosmosAccounts = async (): Promise<CosmosDBAccount[]> => {
73100 }
74101 // --- END DEVELOPMENT MOCK ---
75102
76- const accounts = msalInstance . getAllAccounts ( ) ;
77- if ( accounts . length === 0 ) {
78- throw new Error ( "No signed-in user found." ) ;
79- }
103+ try {
104+ const accounts = msalInstance . getAllAccounts ( ) ;
105+ if ( accounts . length === 0 ) {
106+ throw new Error ( "No signed-in user found." ) ;
107+ }
80108
81- // acquire token for backend API (must be set in loginRequest.scopes)
82- const response = await msalInstance . acquireTokenSilent ( {
83- ...loginRequest ,
84- account : accounts [ 0 ] ,
85- } ) ;
109+ // acquire token for backend API (must be set in loginRequest.scopes)
110+ const response = await msalInstance . acquireTokenSilent ( {
111+ ...loginRequest ,
112+ account : accounts [ 0 ] ,
113+ } ) ;
86114
87- const accessToken = response . accessToken ;
88-
89- console . log ( "Fetching Azure cosmosdb accounts from backend..." ) ;
90- const responseApi = await fetch ( `${ API_BASE_URL } /azure/cosmos_accounts` , {
91- method : 'GET' ,
92- headers : {
93- 'Authorization' : `Bearer ${ accessToken } ` ,
94- } ,
95- } ) ;
115+ const accessToken = response . accessToken ;
116+
117+ console . log ( "Fetching Azure cosmosdb accounts from backend..." ) ;
118+ const responseApi = await fetch ( `${ API_BASE_URL } /azure/cosmos_accounts` , {
119+ method : 'GET' ,
120+ headers : {
121+ 'Authorization' : `Bearer ${ accessToken } ` ,
122+ } ,
123+ } ) ;
96124
97- if ( ! responseApi . ok ) {
98- const errorData = await responseApi . json ( ) . catch ( ( ) => ( { } ) ) ;
99- const errorMessage = errorData . detail || errorData . message || `Could not load Azure resource list from server. Status: ${ responseApi . status } ` ;
100- throw new Error ( errorMessage ) ;
125+ if ( ! responseApi . ok ) {
126+ const errorData = await responseApi . json ( ) . catch ( ( ) => ( { } ) ) ;
127+ const errorMessage = errorData . detail || errorData . message || `Could not load Azure resource list from server. Status: ${ responseApi . status } ` ;
128+ throw new Error ( errorMessage ) ;
129+ }
130+
131+ return responseApi . json ( ) ;
132+ } catch ( error ) {
133+ // Handle authentication errors with user-friendly messages
134+ if ( isAuthenticationExpiredError ( error ) ) {
135+ throw new Error ( getAuthErrorMessage ( error ) ) ;
136+ }
137+ // Re-throw other errors as-is
138+ throw error ;
101139 }
102-
103- return responseApi . json ( ) ;
104140} ;
105141
106142
@@ -129,18 +165,9 @@ export const getDatabasesForAccount = async (accountId: string): Promise<DbInfo[
129165 // --- END DEVELOPMENT MOCK ---
130166
131167 console . log ( `Fetching databases for account ID ${ accountId } from backend...` ) ;
132- const accounts = msalInstance . getAllAccounts ( ) ;
133- if ( accounts . length === 0 ) {
134- throw new Error ( "No signed-in user found." ) ;
135- }
136-
137- // acquire token for backend API (must be set in loginRequest.scopes)
138- const tokenResponse = await msalInstance . acquireTokenSilent ( {
139- ...loginRequest ,
140- account : accounts [ 0 ] ,
141- } ) ;
142-
143- const accessToken = tokenResponse . accessToken ;
168+
169+ // Use helper function to get authenticated token with proper error handling
170+ const accessToken = await getAuthenticatedToken ( ) ;
144171
145172 const response = await fetch ( `${ API_BASE_URL } /azure/account_details` , {
146173 method : 'POST' ,
@@ -179,18 +206,9 @@ export const getCollectionInfo = async (collectionName: string, resource: Select
179206 return Promise . reject ( new Error ( `Mock collection info not found for ${ collectionName } ` ) ) ;
180207 }
181208 // --- END DEVELOPMENT MOCK ---
182- const accounts = msalInstance . getAllAccounts ( ) ;
183- if ( accounts . length === 0 ) {
184- throw new Error ( "No signed-in user found." ) ;
185- }
186-
187- // acquire token for backend API (must be set in loginRequest.scopes)
188- const tokenResponse = await msalInstance . acquireTokenSilent ( {
189- ...loginRequest ,
190- account : accounts [ 0 ] ,
191- } ) ;
192-
193- const accessToken = tokenResponse . accessToken ;
209+
210+ // Use helper function to get authenticated token with proper error handling
211+ const accessToken = await getAuthenticatedToken ( ) ;
194212
195213 console . log ( `Fetching info for collection: ${ collectionName } from backend...` ) ;
196214 const response = await fetch ( `${ API_BASE_URL } /azure/collection_info` , {
@@ -242,13 +260,10 @@ export const runMongoQuery = async (accountId: string, query: string, resource:
242260 }
243261 // --- END DEVELOPMENT MOCK ---
244262 console . log ( `Fetching databases for account ID ${ accountId } from backend...` ) ;
245- const accounts = msalInstance . getAllAccounts ( ) ;
246- const tokenResponse = await msalInstance . acquireTokenSilent ( {
247- ...loginRequest ,
248- account : accounts [ 0 ] ,
249- } ) ;
250-
251- const accessToken = tokenResponse . accessToken ;
263+
264+ // Use helper function to get authenticated token with proper error handling
265+ const accessToken = await getAuthenticatedToken ( ) ;
266+
252267 console . log ( `Sending query for execution on ${ resource . databaseName } to backend...` ) ;
253268 const response = await fetch ( `${ API_BASE_URL } /query/execute` , {
254269 method : 'POST' ,
0 commit comments