Skip to content

Commit f08d28d

Browse files
committed
Merge remote-tracking branch 'origin/main' into mtewani/partial-errors
2 parents c616528 + e8865f2 commit f08d28d

File tree

9 files changed

+35
-17
lines changed

9 files changed

+35
-17
lines changed

.changeset/fluffy-otters-whisper.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/app-check': patch
3+
---
4+
5+
Improve error handling in AppCheck. The publicly-exported `getToken()` will now throw `internalError` strings it was previously ignoring.

.github/workflows/release-pr.yml

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ jobs:
2424
release:
2525
name: Create Release PR
2626
runs-on: ubuntu-latest
27+
permissions:
28+
pull-requests: write
29+
contents: write
2730
if: ${{ !startsWith(github.event.head_commit.message, 'Version Packages (#') }}
2831
steps:
2932
- name: Checkout Repo

packages/app-check/src/api.ts

+3
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ export async function getToken(
209209
if (result.error) {
210210
throw result.error;
211211
}
212+
if (result.internalError) {
213+
throw result.internalError;
214+
}
212215
return { token: result.token };
213216
}
214217

packages/app-check/src/errors.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const enum AppCheckError {
2727
STORAGE_GET = 'storage-get',
2828
STORAGE_WRITE = 'storage-set',
2929
RECAPTCHA_ERROR = 'recaptcha-error',
30+
INITIAL_THROTTLE = 'initial-throttle',
3031
THROTTLED = 'throttled'
3132
}
3233

@@ -54,7 +55,8 @@ const ERRORS: ErrorMap<AppCheckError> = {
5455
[AppCheckError.STORAGE_WRITE]:
5556
'Error thrown when writing to storage. Original error: {$originalErrorMessage}.',
5657
[AppCheckError.RECAPTCHA_ERROR]: 'ReCAPTCHA error.',
57-
[AppCheckError.THROTTLED]: `Requests throttled due to {$httpStatus} error. Attempts allowed again after {$time}`
58+
[AppCheckError.INITIAL_THROTTLE]: `{$httpStatus} error. Attempts allowed again after {$time}`,
59+
[AppCheckError.THROTTLED]: `Requests throttled due to previous {$httpStatus} error. Attempts allowed again after {$time}`
5860
};
5961

6062
interface ErrorParams {
@@ -66,6 +68,7 @@ interface ErrorParams {
6668
[AppCheckError.STORAGE_OPEN]: { originalErrorMessage?: string };
6769
[AppCheckError.STORAGE_GET]: { originalErrorMessage?: string };
6870
[AppCheckError.STORAGE_WRITE]: { originalErrorMessage?: string };
71+
[AppCheckError.INITIAL_THROTTLE]: { time: string; httpStatus: number };
6972
[AppCheckError.THROTTLED]: { time: string; httpStatus: number };
7073
}
7174

packages/app-check/src/internal-api.test.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ describe('internal api', () => {
163163
const error = new Error('oops, something went wrong');
164164
stub(client, 'exchangeToken').returns(Promise.reject(error));
165165

166-
const token = await getToken(appCheck as AppCheckService);
166+
const token = await getToken(appCheck as AppCheckService, false, true);
167167

168168
expect(reCAPTCHASpy).to.be.called;
169169
expect(token).to.deep.equal({
@@ -186,7 +186,7 @@ describe('internal api', () => {
186186
const error = new Error('oops, something went wrong');
187187
stub(client, 'exchangeToken').returns(Promise.reject(error));
188188

189-
const token = await getToken(appCheck as AppCheckService);
189+
const token = await getToken(appCheck as AppCheckService, false, true);
190190

191191
expect(token).to.deep.equal({
192192
token: formatDummyToken(defaultTokenErrorData),
@@ -208,7 +208,7 @@ describe('internal api', () => {
208208
const reCAPTCHASpy = stubGetRecaptchaToken('', false);
209209
const exchangeTokenStub = stub(client, 'exchangeToken');
210210

211-
const token = await getToken(appCheck as AppCheckService);
211+
const token = await getToken(appCheck as AppCheckService, false, true);
212212

213213
expect(reCAPTCHASpy).to.be.called;
214214
expect(exchangeTokenStub).to.not.be.called;
@@ -290,7 +290,6 @@ describe('internal api', () => {
290290
});
291291

292292
it('calls 3P error handler if there is an error getting a token', async () => {
293-
stub(console, 'error');
294293
const appCheck = initializeAppCheck(app, {
295294
provider: new ReCaptchaV3Provider(FAKE_SITE_KEY),
296295
isTokenAutoRefreshEnabled: true
@@ -314,7 +313,6 @@ describe('internal api', () => {
314313
});
315314

316315
it('ignores listeners that throw', async () => {
317-
stub(console, 'error');
318316
const appCheck = initializeAppCheck(app, {
319317
provider: new ReCaptchaV3Provider(FAKE_SITE_KEY),
320318
isTokenAutoRefreshEnabled: true

packages/app-check/src/internal-api.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ export function formatDummyToken(
6060
*/
6161
export async function getToken(
6262
appCheck: AppCheckService,
63-
forceRefresh = false
63+
forceRefresh = false,
64+
shouldLogErrors = false
6465
): Promise<AppCheckTokenResult> {
6566
const app = appCheck.app;
6667
ensureActivated(app);
@@ -136,11 +137,14 @@ export async function getToken(
136137
state.token = tokenFromDebugExchange;
137138
return { token: tokenFromDebugExchange.token };
138139
} catch (e) {
139-
if ((e as FirebaseError).code === `appCheck/${AppCheckError.THROTTLED}`) {
140+
if (
141+
(e as FirebaseError).code === `appCheck/${AppCheckError.THROTTLED}` ||
142+
(e as FirebaseError).code ===
143+
`appCheck/${AppCheckError.INITIAL_THROTTLE}`
144+
) {
140145
// Warn if throttled, but do not treat it as an error.
141146
logger.warn((e as FirebaseError).message);
142-
} else {
143-
// `getToken()` should never throw, but logging error text to console will aid debugging.
147+
} else if (shouldLogErrors) {
144148
logger.error(e);
145149
}
146150
// Return dummy token and error
@@ -167,11 +171,13 @@ export async function getToken(
167171
}
168172
token = await getStateReference(app).exchangeTokenPromise;
169173
} catch (e) {
170-
if ((e as FirebaseError).code === `appCheck/${AppCheckError.THROTTLED}`) {
174+
if (
175+
(e as FirebaseError).code === `appCheck/${AppCheckError.THROTTLED}` ||
176+
(e as FirebaseError).code === `appCheck/${AppCheckError.INITIAL_THROTTLE}`
177+
) {
171178
// Warn if throttled, but do not treat it as an error.
172179
logger.warn((e as FirebaseError).message);
173-
} else {
174-
// `getToken()` should never throw, but logging error text to console will aid debugging.
180+
} else if (shouldLogErrors) {
175181
logger.error(e);
176182
}
177183
// Always save error to be added to dummy token.

packages/app-check/src/providers.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class ReCaptchaV3Provider implements AppCheckProvider {
9292
Number((e as FirebaseError).customData?.httpStatus),
9393
this._throttleData
9494
);
95-
throw ERROR_FACTORY.create(AppCheckError.THROTTLED, {
95+
throw ERROR_FACTORY.create(AppCheckError.INITIAL_THROTTLE, {
9696
time: getDurationString(
9797
this._throttleData.allowRequestsAfter - Date.now()
9898
),
@@ -185,7 +185,7 @@ export class ReCaptchaEnterpriseProvider implements AppCheckProvider {
185185
Number((e as FirebaseError).customData?.httpStatus),
186186
this._throttleData
187187
);
188-
throw ERROR_FACTORY.create(AppCheckError.THROTTLED, {
188+
throw ERROR_FACTORY.create(AppCheckError.INITIAL_THROTTLE, {
189189
time: getDurationString(
190190
this._throttleData.allowRequestsAfter - Date.now()
191191
),

packages/vertexai/test-utils/convert-mocks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const { join } = require('path');
2727

2828
const mockResponseDir = join(
2929
__dirname,
30-
'vertexai-sdk-test-data/mock-responses'
30+
'vertexai-sdk-test-data/mock-responses/vertexai'
3131
);
3232

3333
async function main(): Promise<void> {

scripts/update_vertexai_responses.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# This script replaces mock response files for Vertex AI unit tests with a fresh
1818
# clone of the shared repository of Vertex AI test data.
1919

20-
RESPONSES_VERSION='v6.*' # The major version of mock responses to use
20+
RESPONSES_VERSION='v7.*' # The major version of mock responses to use
2121
REPO_NAME="vertexai-sdk-test-data"
2222
REPO_LINK="https://github.com/FirebaseExtended/$REPO_NAME.git"
2323

0 commit comments

Comments
 (0)