@adaptic/backend-legacy 0.0.975 → 0.0.976
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server.cjs +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptic/backend-legacy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.976",
|
|
4
4
|
"description": "Backend executable CRUD functions with dynamic variables construction, and type definitions for the Adaptic AI platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "index.d.ts",
|
package/server.cjs
CHANGED
|
@@ -284,10 +284,27 @@ const startServer = async () => {
|
|
|
284
284
|
// Throw `UNAUTHENTICATED` so Apollo's HTTP transport returns a
|
|
285
285
|
// GraphQL-shaped error response. The `formatError` hook above
|
|
286
286
|
// preserves the `code` extension.
|
|
287
|
+
//
|
|
288
|
+
// `extensions.http.status: 401` is essential and easy to miss:
|
|
289
|
+
// when `context()` throws, Apollo Server takes the
|
|
290
|
+
// `errorResponse` path (ApolloServer.js#executeHTTPGraphQLRequest
|
|
291
|
+
// catch block) which BYPASSES the request pipeline entirely —
|
|
292
|
+
// willSendResponse plugins do not fire. The only mechanism left
|
|
293
|
+
// for setting the HTTP status is `extensions.http.status` on the
|
|
294
|
+
// thrown error itself, which `normalizeAndFormatErrors` lifts
|
|
295
|
+
// into the response head and then strips from the body so it does
|
|
296
|
+
// not leak. Without this, every auth failure ships as HTTP 500,
|
|
297
|
+
// and Apollo Client's observable pipeline crashes on the 5xx +
|
|
298
|
+
// GraphQL-body combination (`Cannot read properties of undefined
|
|
299
|
+
// (reading 'write')`), leaving consumer `await client.query(...)`
|
|
300
|
+
// promises that neither resolve nor reject — which is precisely
|
|
301
|
+
// how /configure/trading-policy ended up locked in a permanent
|
|
302
|
+
// loading state.
|
|
287
303
|
throw new graphql_1.GraphQLError('Unauthenticated', {
|
|
288
304
|
extensions: {
|
|
289
305
|
code: 'UNAUTHENTICATED',
|
|
290
306
|
reason,
|
|
307
|
+
http: { status: 401 },
|
|
291
308
|
},
|
|
292
309
|
});
|
|
293
310
|
}
|
|
@@ -343,10 +360,17 @@ const startServer = async () => {
|
|
|
343
360
|
logger_1.logger.warn('WebSocket auth rejected — closing connection', {
|
|
344
361
|
reason,
|
|
345
362
|
});
|
|
363
|
+
// graphql-ws closes the connection rather than producing an HTTP
|
|
364
|
+
// response, so `extensions.http.status` is irrelevant here — but
|
|
365
|
+
// we include it for symmetry with the HTTP context above. Any
|
|
366
|
+
// future code that funnels a WS-rejected GraphQLError back into
|
|
367
|
+
// an HTTP response (e.g. a graceful-degrade fallback) will get
|
|
368
|
+
// the correct status without further changes.
|
|
346
369
|
throw new graphql_1.GraphQLError('Unauthenticated', {
|
|
347
370
|
extensions: {
|
|
348
371
|
code: 'UNAUTHENTICATED',
|
|
349
372
|
reason,
|
|
373
|
+
http: { status: 401 },
|
|
350
374
|
},
|
|
351
375
|
});
|
|
352
376
|
}
|