-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(clerk-js): Improve Token.create to handle error due to network …
…failure (#3035) Error resolved by returning an empty string or null instead of trying to decode the `jwt` property from the response data. After this fix an `token.getRawString()` will return an empty string and `session.getToken()` will return `null` on Network failure and when request fails and browser is offline. Current error message example: ``` Error: ClerkJS: Token refresh failed (error='Cannot read properties of null (reading 'jwt')') ```
- Loading branch information
Showing
10 changed files
with
224 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@clerk/clerk-js': patch | ||
--- | ||
|
||
Update token refresh mechanism to handle network failures without raising an error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { createFapiClient } from '../fapiClient'; | ||
import { mockDevClerkInstance, mockFetch, mockNetworkFailedFetch } from '../test/fixtures'; | ||
import { BaseResource } from './internal'; | ||
import { Token } from './Token'; | ||
|
||
describe('Token', () => { | ||
describe('create', () => { | ||
afterEach(() => { | ||
// @ts-ignore | ||
global.fetch?.mockClear(); | ||
BaseResource.clerk = null as any; | ||
}); | ||
|
||
it('with http 500 throws error', async () => { | ||
mockFetch(false, 500); | ||
BaseResource.clerk = { getFapiClient: () => createFapiClient(mockDevClerkInstance) } as any; | ||
|
||
await expect(Token.create('/path/to/tokens')).rejects.toMatchObject({ | ||
message: '500', | ||
}); | ||
|
||
expect(global.fetch).toHaveBeenCalledWith( | ||
'https://clerk.example.com/v1/path/to/tokens?_clerk_js_version=test-0.0.0', | ||
// TODO(dimkl): omit extra params from fetch request (eg path, url) - remove expect.objectContaining | ||
expect.objectContaining({ | ||
method: 'POST', | ||
body: '', | ||
credentials: 'include', | ||
headers: new Headers(), | ||
}), | ||
); | ||
}); | ||
|
||
describe('with offline browser and network failure', () => { | ||
let warnSpy; | ||
|
||
beforeEach(() => { | ||
Object.defineProperty(window.navigator, 'onLine', { | ||
writable: true, | ||
value: false, | ||
}); | ||
warnSpy = jest.spyOn(console, 'warn').mockReturnValue(); | ||
}); | ||
|
||
afterEach(() => { | ||
Object.defineProperty(window.navigator, 'onLine', { | ||
writable: true, | ||
value: true, | ||
}); | ||
warnSpy.mockRestore(); | ||
}); | ||
|
||
it('create returns empty raw string', async () => { | ||
mockNetworkFailedFetch(); | ||
BaseResource.clerk = { getFapiClient: () => createFapiClient(mockDevClerkInstance) } as any; | ||
|
||
const token = await Token.create('/path/to/tokens'); | ||
|
||
expect(global.fetch).toHaveBeenCalledWith( | ||
'https://clerk.example.com/v1/path/to/tokens?_clerk_js_version=test-0.0.0', | ||
// TODO(dimkl): omit extra params from fetch request (eg path, url) - remove expect.objectContaining | ||
expect.objectContaining({ | ||
method: 'POST', | ||
body: '', | ||
credentials: 'include', | ||
headers: new Headers(), | ||
}), | ||
); | ||
|
||
expect(token.getRawString()).toEqual(''); | ||
expect(warnSpy).toBeCalled(); | ||
}); | ||
}); | ||
|
||
describe('with online browser and network failure', () => { | ||
it('throws error', async () => { | ||
mockNetworkFailedFetch(); | ||
BaseResource.clerk = { getFapiClient: () => createFapiClient(mockDevClerkInstance) } as any; | ||
|
||
await expect(Token.create('/path/to/tokens')).rejects.toMatchObject({ | ||
message: | ||
'ClerkJS: Network error at "https://clerk.example.com/v1/path/to/tokens?_clerk_js_version=test-0.0.0" - TypeError: Failed to fetch. Please try again.', | ||
}); | ||
|
||
expect(global.fetch).toHaveBeenCalledWith( | ||
'https://clerk.example.com/v1/path/to/tokens?_clerk_js_version=test-0.0.0', | ||
// TODO(dimkl): omit extra params from fetch request (eg path, url) - remove expect.objectContaining | ||
expect.objectContaining({ | ||
method: 'POST', | ||
body: '', | ||
credentials: 'include', | ||
headers: new Headers(), | ||
}), | ||
); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters