Files
web/lib/graphql/_request.ts
2024-09-24 17:41:50 +02:00

106 lines
3.1 KiB
TypeScript

import "server-only"
import { ClientError, GraphQLClient } from "graphql-request"
import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import type { DocumentNode } from "graphql"
import type { Data } from "@/types/request"
export async function request<T>(
client: GraphQLClient,
query: string | DocumentNode,
variables?: {},
params?: RequestInit
): Promise<Data<T>> {
try {
if (params?.cache) {
client.requestConfig.cache = params.cache
}
if (params?.headers) {
client.requestConfig.headers = params.headers
}
if (params?.next) {
client.requestConfig.next = params.next
}
if (env.PRINT_QUERY) {
const print = (await import("graphql/language/printer")).print
const rawResponse = await client.rawRequest<T>(
print(query as DocumentNode),
variables,
{
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
}
)
/**
* TODO: Send to Monitoring (Logging and Metrics)
*/
console.log({
complexityLimit: rawResponse.headers.get("x-query-complexity"),
})
console.log({
referenceDepth: rawResponse.headers.get("x-reference-depth"),
})
console.log({ resolverCost: rawResponse.headers.get("x-resolver-cost") })
return {
data: rawResponse.data,
}
}
const print = (await import("graphql/language/printer")).print
const nr = Math.random()
console.log(`START REQUEST ${nr}`)
console.time(`OUTGOING REQUEST ${nr}`)
console.log(`Sending reqeust to ${env.CMS_URL}`)
console.log(`Query:`, print(query as DocumentNode))
console.log(`Variables:`, variables)
const response = await client.request<T>({
document: query,
requestHeaders: {
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
},
variables,
})
console.timeEnd(`OUTGOING REQUEST ${nr}`)
console.log({ response })
return { data: response }
} catch (error) {
if (error instanceof ClientError) {
if (error.response.errors?.length) {
const failedToFetchItem = error.response.errors.find(
(err) => err.message === "Failed to fetch item"
)
if (
failedToFetchItem &&
failedToFetchItem.extensions?.errors === "Object not found!" &&
failedToFetchItem.path?.find((p) => Lang[p as Lang])
) {
/**
* Because of Contentstacks totally obscure way of implementing
* GraphQL where they throw an error when you are querying for
* a single item that is nullable and doesn't exist. This leads
* to the issue where when we have a page that is missing a published
* version for one language, it throws an error which we have to recover
* from here since it isn't an error.
*/
return { data: error.response.data as T }
}
}
}
// console.error("Error in graphql request")
// console.error(error)
throw new Error("Something went wrong")
}
}