Skip to content

Commit

Permalink
Add a new VertexAI error type
Browse files Browse the repository at this point in the history
  • Loading branch information
dlarocque committed May 10, 2024
1 parent ab883d0 commit 5fb071b
Show file tree
Hide file tree
Showing 17 changed files with 556 additions and 166 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-cheetahs-arrive.md
@@ -0,0 +1,5 @@
---
'@firebase/vertexai-preview': patch
---

Add a new VertexAI error type
40 changes: 40 additions & 0 deletions common/api-review/vertexai-preview.api.md
Expand Up @@ -7,6 +7,7 @@
import { AppCheckTokenResult } from '@firebase/app-check-interop-types';
import { FirebaseApp } from '@firebase/app';
import { FirebaseAuthTokenData } from '@firebase/auth-interop-types';
import { FirebaseError } from '@firebase/util';

// @public
export interface BaseParams {
Expand Down Expand Up @@ -102,6 +103,16 @@ export interface EnhancedGenerateContentResponse extends GenerateContentResponse
text: () => string;
}

// @public
export interface ErrorDetails {
// (undocumented)
'@type'?: string;
[key: string]: unknown;
domain?: string;
metadata?: Record<string, unknown>;
reason?: string;
}

// @public
export interface FileData {
// (undocumented)
Expand Down Expand Up @@ -590,6 +601,35 @@ export interface VertexAI {
location: string;
}

// @public
export class VertexAIError extends FirebaseError {
constructor(code: VertexAIErrorCode, message: string, status?: number | undefined, statusText?: string | undefined, errorDetails?: ErrorDetails[] | undefined);
// (undocumented)
readonly code: VertexAIErrorCode;
// (undocumented)
readonly errorDetails?: ErrorDetails[] | undefined;
// (undocumented)
readonly message: string;
readonly stack?: string;
// (undocumented)
readonly status?: number | undefined;
// (undocumented)
readonly statusText?: string | undefined;
}

// @public
export const enum VertexAIErrorCode {
ERROR = "error",
FETCH_ERROR = "fetch-error",
INVALID_CONTENT = "invalid-content",
NO_API_KEY = "no-api-key",
NO_MODEL = "no-model",
NO_PROJECT_ID = "no-project-id",
PARSE_FAILED = "parse-failed",
REQUEST_ERROR = "request-error",
RESPONSE_ERROR = "response-error"
}

// @public
export interface VertexAIOptions {
// (undocumented)
Expand Down
66 changes: 66 additions & 0 deletions docs-devsite/vertexai-preview.errordetails.md
@@ -0,0 +1,66 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# ErrorDetails interface
Details object that may be included in an error response.

<b>Signature:</b>

```typescript
export interface ErrorDetails
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| ["@type"](./vertexai-preview.errordetails.md#errordetails"@type") | string | |
| [domain](./vertexai-preview.errordetails.md#errordetailsdomain) | string | The domain where the error occured. |
| [metadata](./vertexai-preview.errordetails.md#errordetailsmetadata) | Record&lt;string, unknown&gt; | Additonal metadata about the error. |
| [reason](./vertexai-preview.errordetails.md#errordetailsreason) | string | The reason for the error. |

## ErrorDetails."@type"

<b>Signature:</b>

```typescript
'@type'?: string;
```

## ErrorDetails.domain

The domain where the error occured.

<b>Signature:</b>

```typescript
domain?: string;
```

## ErrorDetails.metadata

Additonal metadata about the error.

<b>Signature:</b>

```typescript
metadata?: Record<string, unknown>;
```

## ErrorDetails.reason

The reason for the error.

<b>Signature:</b>

```typescript
reason?: string;
```
27 changes: 27 additions & 0 deletions docs-devsite/vertexai-preview.md
Expand Up @@ -27,6 +27,7 @@ The Vertex AI For Firebase Web SDK.
| --- | --- |
| [ChatSession](./vertexai-preview.chatsession.md#chatsession_class) | ChatSession class that enables sending chat messages and stores history of sent and received messages so far. |
| [GenerativeModel](./vertexai-preview.generativemodel.md#generativemodel_class) | Class for generative model APIs. |
| [VertexAIError](./vertexai-preview.vertexaierror.md#vertexaierror_class) | Error class for the Firebase VertexAI SDK. |

## Enumerations

Expand All @@ -41,6 +42,7 @@ The Vertex AI For Firebase Web SDK.
| [HarmCategory](./vertexai-preview.md#harmcategory) | Harm categories that would cause prompts or candidates to be blocked. |
| [HarmProbability](./vertexai-preview.md#harmprobability) | Probability that a prompt or candidate matches a harm category. |
| [HarmSeverity](./vertexai-preview.md#harmseverity) | Harm severity levels. |
| [VertexAIErrorCode](./vertexai-preview.md#vertexaierrorcode) | Standardized error codes that [VertexAIError](./vertexai-preview.vertexaierror.md#vertexaierror_class) can have. |

## Interfaces

Expand All @@ -54,6 +56,7 @@ The Vertex AI For Firebase Web SDK.
| [CountTokensResponse](./vertexai-preview.counttokensresponse.md#counttokensresponse_interface) | Response from calling [GenerativeModel.countTokens()](./vertexai-preview.generativemodel.md#generativemodelcounttokens)<!-- -->. |
| [Date\_2](./vertexai-preview.date_2.md#date_2_interface) | Protobuf google.type.Date |
| [EnhancedGenerateContentResponse](./vertexai-preview.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponse_interface) | Response object wrapped with helper methods. |
| [ErrorDetails](./vertexai-preview.errordetails.md#errordetails_interface) | Details object that may be included in an error response. |
| [FileData](./vertexai-preview.filedata.md#filedata_interface) | Data pointing to a file uploaded on Google Cloud Storage. |
| [FileDataPart](./vertexai-preview.filedatapart.md#filedatapart_interface) | Content part interface if the part represents [FileData](./vertexai-preview.filedata.md#filedata_interface) |
| [FunctionCall](./vertexai-preview.functioncall.md#functioncall_interface) | A predicted [FunctionCall](./vertexai-preview.functioncall.md#functioncall_interface) returned from the model that contains a string representing the [FunctionDeclaration.name](./vertexai-preview.functiondeclaration.md#functiondeclarationname) and a structured JSON object containing the parameters and their values. |
Expand Down Expand Up @@ -367,3 +370,27 @@ export declare enum HarmSeverity
| HARM\_SEVERITY\_NEGLIGIBLE | <code>&quot;HARM_SEVERITY_NEGLIGIBLE&quot;</code> | |
| HARM\_SEVERITY\_UNSPECIFIED | <code>&quot;HARM_SEVERITY_UNSPECIFIED&quot;</code> | |

## VertexAIErrorCode

Standardized error codes that [VertexAIError](./vertexai-preview.vertexaierror.md#vertexaierror_class) can have.

<b>Signature:</b>

```typescript
export declare const enum VertexAIErrorCode
```

## Enumeration Members

| Member | Value | Description |
| --- | --- | --- |
| ERROR | <code>&quot;error&quot;</code> | A generic error occured. |
| FETCH\_ERROR | <code>&quot;fetch-error&quot;</code> | An error occurred while performing a fetch. |
| INVALID\_CONTENT | <code>&quot;invalid-content&quot;</code> | An error associated with a Content object. |
| NO\_API\_KEY | <code>&quot;no-api-key&quot;</code> | An error occured due to a missing api key. |
| NO\_MODEL | <code>&quot;no-model&quot;</code> | An error occurred due to a missing model. |
| NO\_PROJECT\_ID | <code>&quot;no-project-id&quot;</code> | An error occured due to a missing project id. |
| PARSE\_FAILED | <code>&quot;parse-failed&quot;</code> | An error occured while parsing. |
| REQUEST\_ERROR | <code>&quot;request-error&quot;</code> | An error occurred in a request. |
| RESPONSE\_ERROR | <code>&quot;response-error&quot;</code> | An error occured in a response. |

107 changes: 107 additions & 0 deletions docs-devsite/vertexai-preview.vertexaierror.md
@@ -0,0 +1,107 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# VertexAIError class
Error class for the Firebase VertexAI SDK.

<b>Signature:</b>

```typescript
export declare class VertexAIError extends FirebaseError
```
<b>Extends:</b> [FirebaseError](./util.firebaseerror.md#firebaseerror_class)
## Constructors
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(code, message, status, statusText, errorDetails)](./vertexai-preview.vertexaierror.md#vertexaierrorconstructor) | | Creates a new VertexAIError instance. |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [code](./vertexai-preview.vertexaierror.md#vertexaierrorcode) | | [VertexAIErrorCode](./vertexai-preview.md#vertexaierrorcode) | |
| [errorDetails](./vertexai-preview.vertexaierror.md#vertexaierrorerrordetails) | | [ErrorDetails](./vertexai-preview.errordetails.md#errordetails_interface)<!-- -->\[\] \| undefined | |
| [message](./vertexai-preview.vertexaierror.md#vertexaierrormessage) | | string | |
| [stack](./vertexai-preview.vertexaierror.md#vertexaierrorstack) | | string | Stack trace of the error. |
| [status](./vertexai-preview.vertexaierror.md#vertexaierrorstatus) | | number \| undefined | |
| [statusText](./vertexai-preview.vertexaierror.md#vertexaierrorstatustext) | | string \| undefined | |
## VertexAIError.(constructor)
Creates a new VertexAIError instance.
<b>Signature:</b>
```typescript
constructor(code: VertexAIErrorCode, message: string, status?: number | undefined, statusText?: string | undefined, errorDetails?: ErrorDetails[] | undefined);
```
#### Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| code | [VertexAIErrorCode](./vertexai-preview.md#vertexaierrorcode) | The error code from [VertexAIErrorCode](./vertexai-preview.md#vertexaierrorcode)<!-- -->. |
| message | string | A human-readable message describing the error. |
| status | number \| undefined | Optional HTTP status code of the error response. |
| statusText | string \| undefined | Optional HTTP status text of the error response. |
| errorDetails | [ErrorDetails](./vertexai-preview.errordetails.md#errordetails_interface)<!-- -->\[\] \| undefined | Optional additional details about the error. |
## VertexAIError.code
<b>Signature:</b>
```typescript
readonly code: VertexAIErrorCode;
```
## VertexAIError.errorDetails
<b>Signature:</b>
```typescript
readonly errorDetails?: ErrorDetails[] | undefined;
```
## VertexAIError.message
<b>Signature:</b>
```typescript
readonly message: string;
```
## VertexAIError.stack
Stack trace of the error.
<b>Signature:</b>
```typescript
readonly stack?: string;
```
## VertexAIError.status
<b>Signature:</b>
```typescript
readonly status?: number | undefined;
```
## VertexAIError.statusText
<b>Signature:</b>
```typescript
readonly statusText?: string | undefined;
```
36 changes: 25 additions & 11 deletions packages/vertexai/src/api.test.ts
Expand Up @@ -14,12 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ModelParams } from './types';
import { ModelParams, VertexAIError, VertexAIErrorCode } from './types';
import { getGenerativeModel } from './api';
import { expect } from 'chai';
import { VertexAI } from './public-types';
import { GenerativeModel } from './models/generative-model';
import { VertexError } from './errors';

const fakeVertexAI: VertexAI = {
app: {
Expand All @@ -35,27 +34,42 @@ const fakeVertexAI: VertexAI = {

describe('Top level API', () => {
it('getGenerativeModel throws if no model is provided', () => {
expect(() => getGenerativeModel(fakeVertexAI, {} as ModelParams)).to.throw(
VertexError.NO_MODEL
);
try {
getGenerativeModel(fakeVertexAI, {} as ModelParams);
} catch (e) {
expect((e as VertexAIError).code).includes(VertexAIErrorCode.NO_MODEL);
expect((e as VertexAIError).message).equals('Missing model parameter');
}
});
it('getGenerativeModel throws if no apiKey is provided', () => {
const fakeVertexNoApiKey = {
...fakeVertexAI,
app: { options: { projectId: 'my-project' } }
} as VertexAI;
expect(() =>
getGenerativeModel(fakeVertexNoApiKey, { model: 'my-model' })
).to.throw(VertexError.NO_API_KEY);
try {
getGenerativeModel(fakeVertexNoApiKey, { model: 'my-model' });
} catch (e) {
expect((e as VertexAIError).code).includes(VertexAIErrorCode.NO_API_KEY);
expect((e as VertexAIError).message).equals(
'Missing Firebase app API key'
);
}
});
it('getGenerativeModel throws if no projectId is provided', () => {
const fakeVertexNoProject = {
...fakeVertexAI,
app: { options: { apiKey: 'my-key' } }
} as VertexAI;
expect(() =>
getGenerativeModel(fakeVertexNoProject, { model: 'my-model' })
).to.throw(VertexError.NO_PROJECT_ID);
try {
getGenerativeModel(fakeVertexNoProject, { model: 'my-model' });
} catch (e) {
expect((e as VertexAIError).code).includes(
VertexAIErrorCode.NO_PROJECT_ID
);
expect((e as VertexAIError).message).equals(
'Missing Firebase app project ID'
);
}
});
it('getGenerativeModel gets a GenerativeModel', () => {
const genModel = getGenerativeModel(fakeVertexAI, { model: 'my-model' });
Expand Down
13 changes: 10 additions & 3 deletions packages/vertexai/src/api.ts
Expand Up @@ -21,8 +21,12 @@ import { getModularInstance } from '@firebase/util';
import { DEFAULT_LOCATION, VERTEX_TYPE } from './constants';
import { VertexAIService } from './service';
import { VertexAI, VertexAIOptions } from './public-types';
import { ERROR_FACTORY, VertexError } from './errors';
import { ModelParams, RequestOptions } from './types';
import {
ModelParams,
RequestOptions,
VertexAIError,
VertexAIErrorCode
} from './types';
import { GenerativeModel } from './models/generative-model';

export { ChatSession } from './methods/chat-session';
Expand Down Expand Up @@ -67,7 +71,10 @@ export function getGenerativeModel(
requestOptions?: RequestOptions
): GenerativeModel {
if (!modelParams.model) {
throw ERROR_FACTORY.create(VertexError.NO_MODEL);
throw new VertexAIError(
VertexAIErrorCode.NO_MODEL,
'Missing model parameter'
);
}
return new GenerativeModel(vertexAI, modelParams, requestOptions);
}

0 comments on commit 5fb071b

Please sign in to comment.