diff --git a/.changeset/tiny-donuts-draw.md b/.changeset/tiny-donuts-draw.md new file mode 100644 index 00000000000..be5016d0ab2 --- /dev/null +++ b/.changeset/tiny-donuts-draw.md @@ -0,0 +1,5 @@ +--- +'@firebase/functions': patch +--- + +Update public `FunctionsErrorCode` type to include "functions/" prefix. diff --git a/common/api-review/functions.api.md b/common/api-review/functions.api.md index 8c68b578020..90c26814746 100644 --- a/common/api-review/functions.api.md +++ b/common/api-review/functions.api.md @@ -24,7 +24,10 @@ export interface FunctionsError extends FirebaseError { } // @public -export type FunctionsErrorCode = 'ok' | 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'not-found' | 'already-exists' | 'permission-denied' | 'resource-exhausted' | 'failed-precondition' | 'aborted' | 'out-of-range' | 'unimplemented' | 'internal' | 'unavailable' | 'data-loss' | 'unauthenticated'; +export type FunctionsErrorCode = `functions/${FunctionsErrorCodeCore}`; + +// @public +export type FunctionsErrorCodeCore = 'ok' | 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'not-found' | 'already-exists' | 'permission-denied' | 'resource-exhausted' | 'failed-precondition' | 'aborted' | 'out-of-range' | 'unimplemented' | 'internal' | 'unavailable' | 'data-loss' | 'unauthenticated'; // @public export function getFunctions(app?: FirebaseApp, regionOrCustomDomain?: string): Functions; diff --git a/packages/functions-compat/src/callable.test.ts b/packages/functions-compat/src/callable.test.ts index cf7c58090fe..b04592efb76 100644 --- a/packages/functions-compat/src/callable.test.ts +++ b/packages/functions-compat/src/callable.test.ts @@ -35,9 +35,7 @@ async function expectError( await promise; } catch (e) { failed = true; - // Errors coming from callable functions usually have the functions - // code in the message since it's thrown inside functions. - expect(e.code).to.match(new RegExp(`functions.*/${code}`)); + expect(e.code).to.equal(code); expect(e.message).to.equal(message); expect(e.details).to.deep.equal(details); } @@ -106,25 +104,29 @@ describe('Firebase Functions > Call', () => { it('missing result', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('missingResultTest'); - await expectError(func(), 'internal', 'Response is missing data field.'); + await expectError( + func(), + 'functions/internal', + 'Response is missing data field.' + ); }); it('unhandled error', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('unhandledErrorTest'); - await expectError(func(), 'internal', 'internal'); + await expectError(func(), 'functions/internal', 'internal'); }); it('unknown error', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('unknownErrorTest'); - await expectError(func(), 'internal', 'internal'); + await expectError(func(), 'functions/internal', 'internal'); }); it('explicit error', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('explicitErrorTest'); - await expectError(func(), 'out-of-range', 'explicit nope', { + await expectError(func(), 'functions/out-of-range', 'explicit nope', { start: 10, end: 20, long: 30 @@ -134,12 +136,16 @@ describe('Firebase Functions > Call', () => { it('http error', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('httpErrorTest'); - await expectError(func(), 'invalid-argument', 'invalid-argument'); + await expectError(func(), 'functions/invalid-argument', 'invalid-argument'); }); it('timeout', async () => { const functions = createTestService(app, region); const func = functions.httpsCallable('timeoutTest', { timeout: 10 }); - await expectError(func(), 'deadline-exceeded', 'deadline-exceeded'); + await expectError( + func(), + 'functions/deadline-exceeded', + 'deadline-exceeded' + ); }); }); diff --git a/packages/functions/src/callable.test.ts b/packages/functions/src/callable.test.ts index eda81d53bdf..1d8ae0cdb31 100644 --- a/packages/functions/src/callable.test.ts +++ b/packages/functions/src/callable.test.ts @@ -17,7 +17,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { FirebaseApp } from '@firebase/app'; -import { FunctionsErrorCode } from './public-types'; +import { FunctionsErrorCodeCore } from './public-types'; import { Provider, ComponentContainer, @@ -44,7 +44,7 @@ export const TEST_PROJECT = require('../../../config/project.json'); // https://github.com/chaijs/chai/issues/608 async function expectError( promise: Promise, - code: FunctionsErrorCode, + code: FunctionsErrorCodeCore, message: string, details?: any ): Promise { diff --git a/packages/functions/src/error.ts b/packages/functions/src/error.ts index b30abbdfe6a..d6f59fd95d3 100644 --- a/packages/functions/src/error.ts +++ b/packages/functions/src/error.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { FunctionsErrorCode } from './public-types'; +import { FunctionsErrorCodeCore as FunctionsErrorCode } from './public-types'; import { decode } from './serializer'; import { HttpResponseBody } from './service'; import { FirebaseError } from '@firebase/util'; diff --git a/packages/functions/src/index.ts b/packages/functions/src/index.ts index 89dc5e49b4a..7318b3e64b7 100644 --- a/packages/functions/src/index.ts +++ b/packages/functions/src/index.ts @@ -23,5 +23,6 @@ import { registerFunctions } from './config'; export * from './api'; +export * from './public-types'; registerFunctions(fetch.bind(self)); diff --git a/packages/functions/src/public-types.ts b/packages/functions/src/public-types.ts index 675c0133ddb..f1c5d23ccba 100644 --- a/packages/functions/src/public-types.ts +++ b/packages/functions/src/public-types.ts @@ -72,6 +72,30 @@ export interface Functions { customDomain: string | null; } +/** + * Functions error code string appended after "functions/" product prefix. + * See {@link FunctionsErrorCode} for full documentation of codes. + * @public + */ +export type FunctionsErrorCodeCore = + | 'ok' + | 'cancelled' + | 'unknown' + | 'invalid-argument' + | 'deadline-exceeded' + | 'not-found' + | 'already-exists' + | 'permission-denied' + | 'resource-exhausted' + | 'failed-precondition' + | 'aborted' + | 'out-of-range' + | 'unimplemented' + | 'internal' + | 'unavailable' + | 'data-loss' + | 'unauthenticated'; + /** * The set of Firebase Functions status codes. The codes are the same at the * ones exposed by gRPC here: @@ -112,24 +136,7 @@ export interface Functions { * credentials for the operation. * @public */ -export type FunctionsErrorCode = - | 'ok' - | 'cancelled' - | 'unknown' - | 'invalid-argument' - | 'deadline-exceeded' - | 'not-found' - | 'already-exists' - | 'permission-denied' - | 'resource-exhausted' - | 'failed-precondition' - | 'aborted' - | 'out-of-range' - | 'unimplemented' - | 'internal' - | 'unavailable' - | 'data-loss' - | 'unauthenticated'; +export type FunctionsErrorCode = `functions/${FunctionsErrorCodeCore}`; /** * An error returned by the Firebase Functions client SDK.