Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
83 changes: 37 additions & 46 deletions firebase-vscode/src/data-connect/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ import { EmulatorsController } from "../core/emulators";
import { dataConnectConfigs } from "../data-connect/config";

import { firebaseRC } from "../core/config";
import { executeGraphQL } from "../../../src/dataconnect/dataplaneClient";
import {
dataconnectDataplaneClient,
executeGraphQL,
DATACONNECT_API_VERSION,
} from "../../../src/dataconnect/dataplaneClient";
import {
ExecuteGraphqlRequest,
ExecuteGraphqlResponse,
ExecuteGraphqlResponseError,
Impersonation,
} from "../dataconnect/types";
import { ClientResponse } from "../apiv2";
import { Client, ClientResponse } from "../../../src/apiv2";
import { InstanceType } from "./code-lens-provider";
import { pluginLogger } from "../logger-wrapper";
import { DataConnectToolkit } from "./toolkit";
Expand Down Expand Up @@ -78,47 +82,35 @@ export class DataConnectService {
return response.text();
}
private async handleProdResponse(
clientResponse: ClientResponse<
response: ClientResponse<
ExecuteGraphqlResponse | ExecuteGraphqlResponseError
>,
): Promise<ExecutionResult> {
if (!(clientResponse.status >= 200 && clientResponse.status < 300)) {
if (!(response.status >= 200 && response.status < 300)) {
const errorResponse =
clientResponse as ClientResponse<ExecuteGraphqlResponseError>;
response as ClientResponse<ExecuteGraphqlResponseError>;
throw new DataConnectError(
`Request failed with status ${clientResponse.status}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It swallowed the error message here.

errorResponse.body.error.message,
`Prod Request failed with status ${response.status}\nMessage ${errorResponse?.body?.error?.message}`,
);
}
const successResponse =
clientResponse as ClientResponse<ExecuteGraphqlResponse>;
const successResponse = response as ClientResponse<ExecuteGraphqlResponse>;
return successResponse.body;
}

private async handleValidResponse(
response: Response,
private async handleEmulatorResponse(
response: ClientResponse<
ExecuteGraphqlResponse | ExecuteGraphqlResponseError
>,
): Promise<ExecutionResult> {
const json = await this.decodeResponse(response, "application/json");
assertExecutionResult(json);

return json;
}

private async handleInvalidResponse(response: Response): Promise<never> {
const cause = await this.decodeResponse(response);

throw new DataConnectError(
`Request failed with status ${response.status}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It swallowed the error message here.

cause,
);
}

private handleResponse(response: Response): Promise<ExecutionResult> {
if (response.status >= 200 && response.status < 300) {
return this.handleValidResponse(response);
if (!(response.status >= 200 && response.status < 300)) {
const errorResponse =
response as ClientResponse<ExecuteGraphqlResponseError>;
throw new DataConnectError(
`Emulator Request failed with status ${response.status}\nMessage ${errorResponse?.body?.error?.message}`,
);
}

return this.handleInvalidResponse(response);
const successResponse = response as ClientResponse<ExecuteGraphqlResponse>;
return successResponse.body;
}

/** Encode a body while handling the fact that "variables" is raw JSON.
Expand Down Expand Up @@ -243,23 +235,22 @@ export class DataConnectService {
extensions: this._auth(),
});
if (params.instance === InstanceType.PRODUCTION) {
const resp = await executeGraphQL(servicePath, prodBody);
const client = dataconnectDataplaneClient();
const resp = await executeGraphQL(client, servicePath, prodBody);
return this.handleProdResponse(resp);
} else {
const resp = await fetch(
(await this.emulatorsController.getLocalEndpoint()) +
`/v1beta/${servicePath}:executeGraphql`,
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"x-mantle-admin": "all",
},
body,
},
);
return this.handleResponse(resp);
const endpoint = this.emulatorsController.getLocalEndpoint();
if (!endpoint) {
throw new DataConnectError(
`Emulator isn't running. Please start your emulator!`,
);
}
const client = new Client({
urlPrefix: endpoint,
apiVersion: DATACONNECT_API_VERSION,
});
const resp = await executeGraphQL(client, servicePath, prodBody);
return this.handleEmulatorResponse(resp);
}
}

Expand Down
17 changes: 11 additions & 6 deletions src/dataconnect/dataplaneClient.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { dataconnectOrigin } from "../api";
import { Client } from "../apiv2";
import { Client, ClientResponse } from "../apiv2";
import * as types from "./types";

const DATACONNECT_API_VERSION = "v1beta";
export const DATACONNECT_API_VERSION = "v1beta";

const dataconnectDataplaneClient = () =>
new Client({
export function dataconnectDataplaneClient(): Client {
return new Client({
urlPrefix: dataconnectOrigin(),
apiVersion: DATACONNECT_API_VERSION,
auth: true,
});
}

export async function executeGraphQL(servicePath: string, body: types.ExecuteGraphqlRequest) {
const res = await dataconnectDataplaneClient().post<
export async function executeGraphQL(
client: Client,
servicePath: string,
body: types.ExecuteGraphqlRequest,
): Promise<ClientResponse<types.ExecuteGraphqlResponse | types.ExecuteGraphqlResponseError>> {
const res = await client.post<
types.ExecuteGraphqlRequest,
types.ExecuteGraphqlResponse | types.ExecuteGraphqlResponseError
>(`${servicePath}:executeGraphql`, body, { resolveOnHTTPError: true });
Expand Down