Skip to content

Conversation

@EmrysMyrddin
Copy link
Collaborator

@EmrysMyrddin EmrysMyrddin commented Nov 14, 2025

Description

This PR add optional experimental support of the coordinate error attribute proposal (graphql/graphql-spec#1200).

This allows us to more easily identify the resolver which is the source of error than with the path which can be difficult to walk, or even lead to unsolvable ambiguities.

Related to GW-501

Usage

Since this is experimental, it has to be explicitly enabled by adding the appropriate plugin to the
Yoga instance:

import { createYoga, useErrorCoordinate } from 'graphql-yoga'
import { schema } from './schema'

export const yoga = createYoga({
  schema,
  plugins: [useErrorCoordinate()]
})

Once enabled, located errors will gain the coordinate attribute:

const myPlugin = {
  onExecutionResult({ result }) {
    if (result.errors) {
      for (const error of result.errors) {
        console.log('Error at', error.coordinate, ':', error.message)
      }
    }
  }
}

Security concerns

Adding a schema coordinate to errors exposes information about the schema, which can be an attack
vector if you rely on the fact your schema is private and secret.

This is why the coordinate attribute is not serialized by default, and will not be exposed to
clients.

If you want to send this information to client, override either each toJSON error's method, or add
a dedicated extension.

import { GraphQLError } from 'graphql'
import { createYoga, maskError, useErrorCoordinate } from 'graphql-yoga'
import { schema } from './schema'

export const yoga = createYoga({
  schema,
  plugins: [useErrorCoordinate()],
  maskedErrors: {
    isDev: process.env['NODE_ENV'] === 'development', // when `isDev` is true, errors are not masked
    maskError: (error, message, isDev) => {
      if (error instanceof GraphQLError) {
        error.toJSON = () => {
          // Get default graphql serialized error representation
          const json = GraphQLError.prototype.toJSON.apply(error)
          // Manually add the coordinate attribute. You can also use extensions instead.
          json.coordinate = error.coordinate
          return json
        }
      }

      // Keep the default error masking implementation
      return maskError(error, message, isDev)
    }
  }
})

@codesandbox
Copy link

codesandbox bot commented Nov 14, 2025

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@EmrysMyrddin EmrysMyrddin changed the title feat(graphql-yoga): add error schema coordinate extension feat(graphql-yoga): add support for experimental error coordinate Nov 14, 2025
@EmrysMyrddin EmrysMyrddin force-pushed the feat/error-schema-coord branch from 89d3ba3 to 947292d Compare November 14, 2025 09:12
@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

Apollo Federation Subgraph Compatibility Results

Federation 1 Support Federation 2 Support
_service🟢
@key (single)🟢
@key (multi)🟢
@key (composite)🟢
repeatable @key🟢
@requires🟢
@provides🟢
federated tracing🟢
@link🟢
@shareable🟢
@tag🟢
@override🟢
@inaccessible🟢
@composeDirective🟢
@interfaceObject🟢

Learn more:

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

💻 Website Preview

The latest changes are available as preview in: https://pr-4288.graphql-yoga.pages.dev

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

✅ Benchmark Results

     ✓ no_errors{mode:graphql}
     ✓ expected_result{mode:graphql}
     ✓ no_errors{mode:graphql-jit}
     ✓ expected_result{mode:graphql-jit}
     ✓ no_errors{mode:graphql-response-cache}
     ✓ expected_result{mode:graphql-response-cache}
     ✓ no_errors{mode:graphql-no-parse-validate-cache}
     ✓ expected_result{mode:graphql-no-parse-validate-cache}
     ✓ no_errors{mode:uws}
     ✓ expected_result{mode:uws}

     checks.......................................: 100.00% ✓ 513164      ✗ 0     
     data_received................................: 2.1 GB  14 MB/s
     data_sent....................................: 103 MB  688 kB/s
     http_req_blocked.............................: avg=1.52µs   min=992ns    med=1.32µs   max=287.97µs p(90)=2µs      p(95)=2.19µs  
     http_req_connecting..........................: avg=2ns      min=0s       med=0s       max=143.88µs p(90)=0s       p(95)=0s      
     http_req_duration............................: avg=364.12µs min=203.54µs med=337.32µs max=18.93ms  p(90)=476.71µs p(95)=496.21µs
       { expected_response:true }.................: avg=364.12µs min=203.54µs med=337.32µs max=18.93ms  p(90)=476.71µs p(95)=496.21µs
     ✓ { mode:graphql-jit }.......................: avg=276.72µs min=203.54µs med=260.66µs max=18.93ms  p(90)=289.7µs  p(95)=300.29µs
     ✓ { mode:graphql-no-parse-validate-cache }...: avg=501.68µs min=408.25µs med=479.42µs max=6.25ms   p(90)=514.5µs  p(95)=533.87µs
     ✓ { mode:graphql-response-cache }............: avg=348.28µs min=265.63µs med=331.96µs max=9.79ms   p(90)=361.6µs  p(95)=371.28µs
     ✓ { mode:graphql }...........................: avg=371.17µs min=280.96µs med=343.42µs max=15.86ms  p(90)=391.26µs p(95)=439.24µs
     ✓ { mode:uws }...............................: avg=366.08µs min=286.06µs med=346.56µs max=6.75ms   p(90)=378.35µs p(95)=391.75µs
     http_req_failed..............................: 0.00%   ✓ 0           ✗ 256582
     http_req_receiving...........................: avg=33.38µs  min=16.68µs  med=32.63µs  max=3.06ms   p(90)=39.65µs  p(95)=41.97µs 
     http_req_sending.............................: avg=8.85µs   min=6.08µs   med=7.82µs   max=1.14ms   p(90)=11.15µs  p(95)=12.31µs 
     http_req_tls_handshaking.....................: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting.............................: avg=321.88µs min=176.84µs med=296.36µs max=18.83ms  p(90)=434.29µs p(95)=452.37µs
     http_reqs....................................: 256582  1710.523179/s
     iteration_duration...........................: avg=579.51µs min=380.18µs med=549.55µs max=19.43ms  p(90)=695.32µs p(95)=717.72µs
     iterations...................................: 256582  1710.523179/s
     vus..........................................: 1       min=1         max=1   
     vus_max......................................: 2       min=2         max=2   

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@graphql-yoga/apollo-link 5.2.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/urql-exchange 5.2.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
graphql-yoga 5.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/nestjs 3.18.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/nestjs-federation 3.18.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-apollo-inline-trace 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/apollo-managed-federation 0.16.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-apollo-usage-report 0.12.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-apq 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-csrf-prevention 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-defer-stream 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-disable-introspection 2.18.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-graphql-sse 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-jwt 3.11.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-persisted-operations 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-prometheus 6.12.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-response-cache 3.19.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/plugin-sofa 3.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/render-apollo-sandbox 0.2.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎
@graphql-yoga/render-graphiql 5.17.0-alpha-20251128101640-816e18742b5d7b260eea8ad3b14ab2d69cc99790 npm ↗︎ unpkg ↗︎

Copy link
Collaborator

Choose a reason for hiding this comment

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

😍

Copy link
Collaborator

@n1ru4l n1ru4l left a comment

Choose a reason for hiding this comment

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

Looks good with me, let's ship it!

@EmrysMyrddin EmrysMyrddin merged commit 66c370c into main Nov 28, 2025
24 checks passed
@EmrysMyrddin EmrysMyrddin deleted the feat/error-schema-coord branch November 28, 2025 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants