Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Vertex GA] Add new endpoint and error message. #8497

Merged
merged 4 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/api-review/vertexai-preview.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ export class VertexAIError extends FirebaseError {

// @public
export const enum VertexAIErrorCode {
API_NOT_ENABLED = "api-not-enabled",
ERROR = "error",
FETCH_ERROR = "fetch-error",
INVALID_CONTENT = "invalid-content",
Expand Down
4 changes: 2 additions & 2 deletions packages/vertexai/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ export const VERTEX_TYPE = 'vertexAI';

export const DEFAULT_LOCATION = 'us-central1';

export const DEFAULT_BASE_URL = 'https://firebaseml.googleapis.com';
export const DEFAULT_BASE_URL = 'https://firebasevertexai.googleapis.com';

export const DEFAULT_API_VERSION = 'v2beta';
export const DEFAULT_API_VERSION = 'v1beta';

export const PACKAGE_VERSION = version;

Expand Down
14 changes: 14 additions & 0 deletions packages/vertexai/src/methods/generate-content.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,18 @@ describe('generateContent()', () => {
).to.be.rejectedWith(/400.*invalid argument/);
expect(mockFetch).to.be.called;
});
it('api not enabled (403)', async () => {
const mockResponse = getMockResponse(
'unary-failure-firebasevertexai-api-not-enabled.json'
);
const mockFetch = stub(globalThis, 'fetch').resolves({
ok: false,
status: 403,
json: mockResponse.json
} as Response);
await expect(
generateContent(fakeApiSettings, 'model', fakeRequestParams)
).to.be.rejectedWith(/firebasevertexai\.googleapis.*my-project/);
expect(mockFetch).to.be.called;
});
});
25 changes: 25 additions & 0 deletions packages/vertexai/src/requests/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { ApiSettings } from '../types/internal';
import { DEFAULT_API_VERSION } from '../constants';
import { VertexAIErrorCode } from '../types';
import { VertexAIError } from '../errors';
import { getMockResponse } from '../../test-utils/mock-response';

use(sinonChai);
use(chaiAsPromised);
Expand Down Expand Up @@ -357,4 +358,28 @@ describe('request methods', () => {
expect(fetchStub).to.be.calledOnce;
});
});
it('Network error, API not enabled', async () => {
const mockResponse = getMockResponse(
'unary-failure-firebasevertexai-api-not-enabled.json'
);
const fetchStub = stub(globalThis, 'fetch').resolves(
mockResponse as Response
);
try {
await makeRequest(
'models/model-name',
Task.GENERATE_CONTENT,
fakeApiSettings,
false,
''
);
} catch (e) {
expect((e as VertexAIError).code).to.equal(
VertexAIErrorCode.API_NOT_ENABLED
);
expect((e as VertexAIError).message).to.include('my-project');
expect((e as VertexAIError).message).to.include('googleapis.com');
}
expect(fetchStub).to.be.calledOnce;
});
});
31 changes: 30 additions & 1 deletion packages/vertexai/src/requests/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import { RequestOptions, VertexAIErrorCode } from '../types';
import { ErrorDetails, RequestOptions, VertexAIErrorCode } from '../types';
import { VertexAIError } from '../errors';
import { ApiSettings } from '../types/internal';
import {
Expand Down Expand Up @@ -151,6 +151,34 @@ export async function makeRequest(
} catch (e) {
// ignored
}
if (
response.status === 403 &&
errorDetails.some(
(detail: ErrorDetails) => detail.reason === 'SERVICE_DISABLED'
) &&
errorDetails.some((detail: ErrorDetails) =>
(
detail.links as Array<Record<string, string>>
)?.[0]?.description.includes(
'Google developers console API activation'
)
)
) {
throw new VertexAIError(
VertexAIErrorCode.API_NOT_ENABLED,
`The Vertex AI for Firebase SDK requires the Firebase Vertex AI API ` +
`firebasevertexai.googleapis.com to be enabled for your ` +
`project. Get started in the Firebase Console` +
` (https://console.firebase.google.com/project/${url.apiSettings.project}/genai/vertex)` +
` or verify that the API is enabled in the Google Cloud` +
` Console (https://console.developers.google.com/apis/api/firebasevertexai.googleapis.com/overview?project=${url.apiSettings.project}).`,
{
status: response.status,
statusText: response.statusText,
errorDetails
}
);
}
throw new VertexAIError(
VertexAIErrorCode.FETCH_ERROR,
`Error fetching from ${url}: [${response.status} ${response.statusText}] ${message}`,
Expand All @@ -165,6 +193,7 @@ export async function makeRequest(
let err = e as Error;
if (
(e as VertexAIError).code !== VertexAIErrorCode.FETCH_ERROR &&
(e as VertexAIError).code !== VertexAIErrorCode.API_NOT_ENABLED &&
e instanceof Error
) {
err = new VertexAIError(
Expand Down
3 changes: 3 additions & 0 deletions packages/vertexai/src/types/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ export const enum VertexAIErrorCode {
/** An error associated with a Content object. */
INVALID_CONTENT = 'invalid-content',

/** An error due to the Firebase API not being enabled in the Console. */
API_NOT_ENABLED = 'api-not-enabled',

/** An error occurred due to a missing Firebase API key. */
NO_API_KEY = 'no-api-key',

Expand Down
Loading