hotfix: graphql connection error handler (#4523)

Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
Anwarul Islam
2024-11-12 21:45:48 +06:00
committed by GitHub
parent 3de3209d5e
commit e1fbe68796
4 changed files with 55 additions and 15 deletions

View File

@@ -13,6 +13,7 @@ import {
printSchema,
} from "graphql"
import { Component, computed, reactive, ref } from "vue"
import { useToast } from "~/composables/toast"
import { getService } from "~/modules/dioc"
import { getI18n } from "~/modules/i18n"
@@ -52,7 +53,11 @@ export type GQLResponseEvent =
}
}
export type ConnectionState = "CONNECTING" | "CONNECTED" | "DISCONNECTED"
export type ConnectionState =
| "CONNECTING"
| "CONNECTED"
| "DISCONNECTED"
| "ERROR"
export type SubscriptionState = "SUBSCRIBING" | "SUBSCRIBED" | "UNSUBSCRIBED"
const GQL = {
@@ -100,10 +105,7 @@ export const gqlMessageEvent = ref<GQLResponseEvent | "reset">()
export const schemaString = computed(() => {
if (!connection.schema) return ""
return printSchema(connection.schema, {
commentDescriptions: true,
})
return printSchema(connection.schema)
})
export const queryFields = computed(() => {
@@ -159,21 +161,40 @@ export const graphqlTypes = computed(() => {
let timeoutSubscription: any
export const connect = async (url: string, headers: GQLHeader[]) => {
export const connect = async (
url: string,
headers: GQLHeader[],
isRunGQLOperation = false
) => {
if (connection.state === "CONNECTED") {
throw new Error(
"A connection is already running. Close it before starting another."
)
}
// Polling
connection.state = "CONNECTED"
const toast = useToast()
const t = getI18n()
connection.state = "CONNECTING"
const poll = async () => {
await getSchema(url, headers)
timeoutSubscription = setTimeout(() => {
poll()
}, GQL_SCHEMA_POLL_INTERVAL)
try {
await getSchema(url, headers)
// polling for schema
if (connection.state !== "CONNECTED") connection.state = "CONNECTED"
timeoutSubscription = setTimeout(() => {
poll()
}, GQL_SCHEMA_POLL_INTERVAL)
} catch (error) {
connection.state = "ERROR"
// Show an error toast if the introspection attempt failed and not while sending a request
if (!isRunGQLOperation) {
toast.error(t("graphql.connection_error_http"))
}
console.error(error)
}
}
await poll()
@@ -221,6 +242,8 @@ const getSchema = async (url: string, headers: GQLHeader[]) => {
const res = await interceptorService.runRequest(reqOptions).response
if (E.isLeft(res)) {
connection.state = "ERROR"
if (
res.left !== "cancellation" &&
res.left.error === "NO_PW_EXT_HOOK" &&
@@ -237,6 +260,17 @@ const getSchema = async (url: string, headers: GQLHeader[]) => {
throw new Error(res.left.toString())
}
if (res.right.status !== 200) {
connection.state = "ERROR"
connection.error = {
type: "HTTP_ERROR",
message: (t: ReturnType<typeof getI18n>) =>
t("graphql.connection_error_http"),
component: undefined,
}
throw new Error("Failed to fetch schema. Status: " + res.right.status)
}
const data = res.right
// HACK : Temporary trailing null character issue from the extension fix
@@ -258,7 +292,7 @@ const getSchema = async (url: string, headers: GQLHeader[]) => {
export const runGQLOperation = async (options: RunQueryOptions) => {
if (connection.state !== "CONNECTED") {
await connect(options.url, options.headers)
await connect(options.url, options.headers, true)
}
const { url, headers, query, variables, auth, operationName, operationType } =