Skip to content

Commit

Permalink
customize not found error message
Browse files Browse the repository at this point in the history
  • Loading branch information
EmrysMyrddin committed Apr 27, 2023
1 parent e661eb4 commit 39714eb
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { usePersistedOperations } from '@graphql-yoga/plugin-persisted-operations'
import {
CustomPersistedQueryErrors,
usePersistedOperations,
} from '@graphql-yoga/plugin-persisted-operations'
import { DocumentNode, parse, validate } from 'graphql'
import { createSchema, createYoga, GraphQLParams } from 'graphql-yoga'

Expand Down Expand Up @@ -115,6 +118,7 @@ describe('Persisted Operations', () => {
expect(body.errors).toBeDefined()
expect(body.errors[0].message).toBe('PersistedQueryOnly')
})

it('allows non-persisted operations via allowArbitraryOperations flag', async () => {
const store = new Map<string, string>()

Expand Down Expand Up @@ -150,6 +154,7 @@ describe('Persisted Operations', () => {
expect(body.errors).toBeUndefined()
expect(body.data).toEqual({ __typename: 'Query' })
})

it('allows non-persisted operations via allowArbitraryOperations based on a header', async () => {
const store = new Map<string, string>()

Expand Down Expand Up @@ -187,6 +192,7 @@ describe('Persisted Operations', () => {
expect(body.errors).toBeUndefined()
expect(body.data).toEqual({ __typename: 'Query' })
})

it('should respect the custom getPersistedQueryKey implementation (Relay)', async () => {
const store = new Map<string, string>()
const yoga = createYoga({
Expand Down Expand Up @@ -356,4 +362,43 @@ describe('Persisted Operations', () => {

expect(validateFn).not.toHaveBeenCalled()
})

it('should allow to customize not found error message with a string', async () => {
const error = await generateNotFoundError({ notFound: 'Not found' })
expect(error.message).toBe('Not found')
})
})

async function generateNotFoundError(customErrors: CustomPersistedQueryErrors) {
const yoga = createYoga({
plugins: [
usePersistedOperations({
getPersistedOperation() {
return null
},
customErrors,
}),
],
schema,
})

const response = await yoga.fetch('http://yoga/graphql', {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
extensions: {
persistedQuery: {
version: 1,
sha256Hash:
'ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38',
},
},
}),
})

const body = await response.json()
expect(body.errors).toBeDefined()
return body.errors[0]
}
19 changes: 18 additions & 1 deletion packages/plugins/persisted-operations/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ export type UsePersistedOperationsOptions = {
* Whether to skip validation of the persisted operation
*/
skipDocumentValidation?: boolean

/**
* Custom errors to be thrown
*/
customErrors?: CustomPersistedQueryErrors
}

export type CustomErrorFactory = string

export type CustomPersistedQueryErrors = {
/**
* Error to be thrown when the persisted operation is not found
*/
notFound?: CustomErrorFactory
}

export function usePersistedOperations<
Expand All @@ -60,6 +74,7 @@ export function usePersistedOperations<
extractPersistedOperationId = defaultExtractPersistedOperationId,
getPersistedOperation,
skipDocumentValidation = false,
customErrors,
}: UsePersistedOperationsOptions): Plugin<TPluginContext> {
const operationASTByRequest = new WeakMap<Request, DocumentNode>()
const persistedOperationRequest = new WeakSet<Request>()
Expand All @@ -84,7 +99,9 @@ export function usePersistedOperations<

const persistedQuery = await getPersistedOperation(persistedOperationKey)
if (persistedQuery == null) {
throw createGraphQLError('PersistedQueryNotFound')
throw createGraphQLError(
customErrors?.notFound ?? 'PersistedQueryNotFound',
)
}

if (typeof persistedQuery === 'object') {
Expand Down

0 comments on commit 39714eb

Please sign in to comment.