Skip to content

Commit

Permalink
Merge pull request #23 from well-known-components/feat/better-errors
Browse files Browse the repository at this point in the history
feat: support single error message
  • Loading branch information
nicosantangelo authored Jul 5, 2022
2 parents 51b82b2 + 1a25f46 commit 2aff958
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
10 changes: 7 additions & 3 deletions etc/thegraph-component.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export namespace createSubgraphComponent {
};
}

// @public (undocumented)
type Error_2 = {
message: string;
};
export { Error_2 as Error }

// @public (undocumented)
export interface ISubgraphComponent {
query: <T>(query: string, variables?: Variables, remainingAttempts?: number) => Promise<T>;
Expand All @@ -42,9 +48,7 @@ export const metricDeclarations: IMetricsComponent.MetricsRecordDefinition<strin
// @public (undocumented)
export type SubgraphResponse<T> = {
data: T;
errors?: {
message: string;
}[];
errors?: Error_2[] | Error_2;
};

// @public (undocumented)
Expand Down
16 changes: 8 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ export async function createSubgraphComponent(
timeoutWait
)

const hasErrors = errors !== undefined
if (hasErrors) {
const errorMessages = Array.isArray(errors) ? errors.map((error) => error.message) : [errors.message]
throw new Error(`GraphQL Error: Invalid response. Errors:\n- ${errorMessages.join("\n- ")}`)
}

const hasInvalidData = !data || Object.keys(data).length === 0
const hasMultipleErrors = errors && errors.length > 1

if (hasInvalidData || hasMultipleErrors) {
throw new Error(
hasMultipleErrors
? `There was a total of ${errors.length}. GraphQL errors:\n- ${errors.join("\n- ")}`
: "GraphQL Error: Invalid response"
)
if (hasInvalidData) {
throw new Error("GraphQL Error: Invalid response.")
}

logger.debug("Success:", logData)
Expand Down
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ export type Variables = Record<string, string[] | string | number | boolean | un
/**
* @public
*/
export type SubgraphResponse<T> = { data: T; errors?: { message: string }[] }
export type Error = { message: string }

/**
* @public
*/
export type SubgraphResponse<T> = { data: T; errors?: Error[] | Error }

/**
* @public
Expand Down
29 changes: 21 additions & 8 deletions test/component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ILoggerComponent } from "@well-known-components/interfaces"
import { IFetchComponent } from "@well-known-components/http-server"
import { randomUUID } from "crypto"
import { setTimeout } from "timers/promises"
import { ISubgraphComponent } from "../src/types"
import { ISubgraphComponent, SubgraphResponse } from "../src/types"
import { createSubgraphComponent } from "../src"
import { SUBGRAPH_URL, test } from "./components"

Expand Down Expand Up @@ -84,7 +84,7 @@ test("subgraph component", function ({ components, stubComponents }) {
})

describe("when the request errors out", () => {
let errorResponseData: { errors: string[] }
let errorResponseData: SubgraphResponse<any>

describe("and the server has an internal error", () => {
beforeEach(() => {
Expand Down Expand Up @@ -167,10 +167,15 @@ test("subgraph component", function ({ components, stubComponents }) {
})

describe("when the query is incorrect", () => {
const errorMessage = "No suitable indexer found for subgraph deployment"

beforeEach(() => {
const { fetch } = components

errorResponseData = { errors: [] }
errorResponseData = {
data: undefined,
errors: { message: errorMessage },
}
response = {
ok: true,
status: 400,
Expand All @@ -190,28 +195,36 @@ test("subgraph component", function ({ components, stubComponents }) {

expect(metrics.increment).toHaveBeenCalledWith("subgraph_errors_total", {
url: SUBGRAPH_URL,
errorMessage: "GraphQL Error: Invalid response",
errorMessage: `GraphQL Error: Invalid response. Errors:\n- ${errorMessage}`,
})
})

describe("and there's an empty errors prop", () => {
beforeEach(() => {
errorResponseData = {
data: {},
errors: undefined,
}
})

it("should throw an Invalid Response error", async () => {
const { subgraph } = components
await expect(subgraph.query("query", {}, 0)).rejects.toThrow("GraphQL Error: Invalid response")
await expect(subgraph.query("query", {}, 0)).rejects.toThrow("GraphQL Error: Invalid response.")
})
})

describe("and there's multiple errors", () => {
beforeEach(() => {
errorResponseData = {
errors: ["some error", "happened"],
data: undefined,
errors: [{ message: "some error" }, { message: "happened" }],
}
})

it("should throw them all", async () => {
const { subgraph } = components
await expect(subgraph.query("query", {}, 0)).rejects.toThrow(
"There was a total of 2. GraphQL errors:\n- some error\n- happened"
"GraphQL Error: Invalid response. Errors:\n- some error\n- happened"
)
})
})
Expand Down Expand Up @@ -247,7 +260,7 @@ test("subgraph component", function ({ components, stubComponents }) {
expect(metrics.increment).toHaveBeenCalledTimes(retries + 1)
expect(metrics.increment).toHaveBeenCalledWith("subgraph_errors_total", {
url: SUBGRAPH_URL,
errorMessage: "GraphQL Error: Invalid response",
errorMessage: `GraphQL Error: Invalid response. Errors:\n- ${errorMessage}`,
})
})
})
Expand Down

0 comments on commit 2aff958

Please sign in to comment.