diff --git a/.changeset/breezy-mangos-refuse.md b/.changeset/breezy-mangos-refuse.md new file mode 100644 index 00000000000..43f98b3cd46 --- /dev/null +++ b/.changeset/breezy-mangos-refuse.md @@ -0,0 +1,5 @@ +--- +"@firebase/auth": patch +--- + +Fix bug where custom errors from blocking functions were being dropped. diff --git a/packages/auth/src/api/errors.ts b/packages/auth/src/api/errors.ts index e70f8523011..a2e8643282e 100644 --- a/packages/auth/src/api/errors.ts +++ b/packages/auth/src/api/errors.ts @@ -22,6 +22,7 @@ import { AuthErrorCode } from '../core/errors'; */ export const enum ServerError { ADMIN_ONLY_OPERATION = 'ADMIN_ONLY_OPERATION', + BLOCKING_FUNCTION_ERROR_RESPONSE = 'BLOCKING_FUNCTION_ERROR_RESPONSE', CAPTCHA_CHECK_FAILED = 'CAPTCHA_CHECK_FAILED', CORS_UNSUPPORTED = 'CORS_UNSUPPORTED', CREDENTIAL_MISMATCH = 'CREDENTIAL_MISMATCH', @@ -199,5 +200,8 @@ export const SERVER_ERROR_MAP: Partial> = { [ServerError.SECOND_FACTOR_EXISTS]: AuthErrorCode.SECOND_FACTOR_ALREADY_ENROLLED, [ServerError.SECOND_FACTOR_LIMIT_EXCEEDED]: - AuthErrorCode.SECOND_FACTOR_LIMIT_EXCEEDED + AuthErrorCode.SECOND_FACTOR_LIMIT_EXCEEDED, + + // Blocking functions related errors. + [ServerError.BLOCKING_FUNCTION_ERROR_RESPONSE]: AuthErrorCode.INTERNAL_ERROR, }; diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts index 990cde7cbb0..ab590ac4406 100644 --- a/packages/auth/src/api/index.test.ts +++ b/packages/auth/src/api/index.test.ts @@ -198,6 +198,37 @@ describe('api/_performApiRequest', () => { expect(mock.calls[0].request).to.eql(request); }); + it('should pass through server messages if applicable', async () => { + mockEndpoint( + Endpoint.SIGN_UP, + { + error: { + code: 400, + message: `${ServerError.BLOCKING_FUNCTION_ERROR_RESPONSE} : Text text text`, + errors: [ + { + message: 'Text text text' + } + ] + } + }, + 400 + ); + const promise = _performApiRequest( + auth, + HttpMethod.POST, + Endpoint.SIGN_UP, + request + ); + let error: FirebaseError; + try { + await promise; + } catch (e) { + error = e; + } + expect(error!.customData!.message).to.eql('Text text text'); + }); + it('should handle unknown server errors', async () => { const mock = mockEndpoint( Endpoint.SIGN_UP, diff --git a/packages/auth/src/api/index.ts b/packages/auth/src/api/index.ts index 7cedb429359..4357db0b535 100644 --- a/packages/auth/src/api/index.ts +++ b/packages/auth/src/api/index.ts @@ -152,7 +152,7 @@ export async function _performFetchWithErrorHandling( return json; } else { const errorMessage = response.ok ? json.errorMessage : json.error.message; - const serverErrorCode = errorMessage.split(' : ')[0] as ServerError; + const [serverErrorCode, serverErrorMessage] = errorMessage.split(' : '); if (serverErrorCode === ServerError.FEDERATED_USER_ID_ALREADY_LINKED) { throw _makeTaggedError( auth, @@ -163,11 +163,15 @@ export async function _performFetchWithErrorHandling( throw _makeTaggedError(auth, AuthErrorCode.EMAIL_EXISTS, json); } const authError = - errorMap[serverErrorCode] || + errorMap[serverErrorCode as ServerError] || ((serverErrorCode .toLowerCase() .replace(/[_\s]+/g, '-') as unknown) as AuthErrorCode); - _fail(auth, authError); + if (serverErrorMessage) { + _fail(auth, authError, {message: serverErrorMessage}); + } else { + _fail(auth, authError); + } } } catch (e) { if (e instanceof FirebaseError) {