Skip to content

Commit

Permalink
fix(sofa): respect error extensions in case of 404 (#3559)
Browse files Browse the repository at this point in the history
* chore(deps): lock file maintenance (#3556)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Return the response only if SOFA returns one

* chore(dependencies): updated changesets for modified dependencies

* Dedupe pnpm lockfile

* chore(deps): lock file maintenance (#3556)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* Add link to SOFA docs

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 19, 2024
1 parent 65cac8d commit 5620283
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 51 deletions.
5 changes: 5 additions & 0 deletions .changeset/@graphql-yoga_plugin-sofa-3559-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-yoga/plugin-sofa": patch
---
dependencies updates:
- Updated dependency [`sofa-api@^0.18.8` ↗︎](https://www.npmjs.com/package/sofa-api/v/0.18.8) (from `^0.18.7`, in `dependencies`)
5 changes: 5 additions & 0 deletions .changeset/soft-turtles-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-yoga/plugin-sofa': patch
---

Fix the issue when SOFA returns 404 response from error extensions returned by a resolver, it will cause the server to continue the request handling with Yoga but instead it should return the response with 404 and the body SOFA returns.
2 changes: 1 addition & 1 deletion packages/plugins/sofa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
"dependencies": {
"@graphql-tools/utils": "^10.3.2",
"sofa-api": "^0.18.7"
"sofa-api": "^0.18.8"
},
"devDependencies": {
"graphql-yoga": "workspace:*"
Expand Down
26 changes: 11 additions & 15 deletions packages/plugins/sofa/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ExecutionArgs, ExecutionResult, SubscriptionArgs } from 'graphql';
import { Plugin, YogaInitialContext, YogaServerInstance } from 'graphql-yoga';
import { mapMaybePromise, Plugin, YogaInitialContext, YogaServerInstance } from 'graphql-yoga';
import { useSofa as createSofaHandler } from 'sofa-api';
import { isPromise } from '@graphql-tools/utils';
import { SofaHandler } from './types.js';

type SofaHandlerConfig = Parameters<typeof createSofaHandler>[0];
Expand Down Expand Up @@ -33,15 +32,10 @@ export function useSofa(config: SofaPluginConfig): Plugin {
schema: onSchemaChangeEventPayload.schema,
context(serverContext: YogaInitialContext) {
const enveloped = getEnveloped(serverContext);
const contextValue$ = enveloped.contextFactory(serverContext);
if (isPromise(contextValue$)) {
return contextValue$.then(contextValue => {
envelopedByContext.set(contextValue, enveloped);
return contextValue;
});
}
envelopedByContext.set(contextValue$, enveloped);
return contextValue$;
return mapMaybePromise(enveloped.contextFactory(serverContext), contextValue$ => {
envelopedByContext.set(contextValue$, enveloped);
return contextValue$;
});
},
execute(
...args:
Expand Down Expand Up @@ -115,10 +109,12 @@ export function useSofa(config: SofaPluginConfig): Plugin {
},
});
},
async onRequest({ request, serverContext, endResponse }) {
const response = await sofaHandler(request, serverContext as Record<string, unknown>);
if (response != null && response.status !== 404) {
endResponse(response);
async onRequest({ request, endResponse, serverContext, url }) {
if (url.pathname.startsWith(config.basePath)) {
const res = await sofaHandler.handleRequest(request, serverContext);
if (res) {
endResponse(res);
}
}
},
};
Expand Down
50 changes: 49 additions & 1 deletion packages/plugins/sofa/tests/sofa.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createSchema, createYoga } from 'graphql-yoga';
import { createGraphQLError, createSchema, createYoga } from 'graphql-yoga';
import { useSofa } from '@graphql-yoga/plugin-sofa';

describe('SOFA Plugin', () => {
Expand Down Expand Up @@ -31,4 +31,52 @@ describe('SOFA Plugin', () => {
});
await expect(res.text()).resolves.toEqual('"Hello, test"');
});
it('forwards error extensions correctly', async () => {
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
me: Account
}
type Account {
id: ID!
name: String!
}
`,
resolvers: {
Query: {
me: () => {
throw createGraphQLError('account not found', {
extensions: {
code: 'ACCOUNT_NOT_FOUND',
http: { status: 404 },
},
});
},
},
},
}),
plugins: [
useSofa({
basePath: '/api',
}),
],
});
for (let i = 0; i < 10; i++) {
const res = await yoga.fetch('http://localhost/api/me');
expect(res.status).toBe(404);
const json = await res.json();
expect(json).toEqual({
errors: [
{
message: 'account not found',
extensions: {
code: 'ACCOUNT_NOT_FOUND',
},
path: ['me'],
},
],
});
}
});
});
63 changes: 29 additions & 34 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5620283

Please sign in to comment.