From 017e7139c9a88fe69f535498b2d991ea773901df Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Tue, 31 Mar 2026 07:38:40 +0000 Subject: [PATCH 1/2] feat: add error handling guidance to generated ORM AGENTS.md - Add Error Handling section with CRITICAL warning about silent error trap - Show correct vs incorrect patterns (try/catch with .execute() vs .unwrap()) - Document .unwrap(), .unwrapOr(), .unwrapOrElse() helpers - Update Stack and Conventions sections to mention .unwrap() alongside .execute() --- .../src/core/codegen/orm/docs-generator.ts | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/graphql/codegen/src/core/codegen/orm/docs-generator.ts b/graphql/codegen/src/core/codegen/orm/docs-generator.ts index d82dd2987..5a204c4cc 100644 --- a/graphql/codegen/src/core/codegen/orm/docs-generator.ts +++ b/graphql/codegen/src/core/codegen/orm/docs-generator.ts @@ -177,7 +177,7 @@ export function generateOrmAgentsDocs( lines.push(''); lines.push('- Prisma-like ORM client for a GraphQL API (TypeScript)'); lines.push(`- ${tableCount} model${tableCount !== 1 ? 's' : ''}${customOpCount > 0 ? `, ${customOpCount} custom operation${customOpCount !== 1 ? 's' : ''}` : ''}`); - lines.push('- All methods return a query builder; call `.execute()` to run'); + lines.push('- All methods return a QueryBuilder; call `.execute()` to run, or `.unwrap()` to throw on error'); lines.push(''); lines.push('## Quick Start'); @@ -192,6 +192,30 @@ export function generateOrmAgentsDocs( lines.push('```'); lines.push(''); + lines.push('## Error Handling'); + lines.push(''); + lines.push('> **CRITICAL:** `.execute()` returns `{ ok, data, errors }` — it does **NOT** throw.'); + lines.push('> A bare `try/catch` around `.execute()` will silently swallow errors.'); + lines.push(''); + lines.push('```typescript'); + lines.push('// WRONG — errors are silently lost:'); + lines.push('try { const r = await db.model.findMany({...}).execute(); } catch (e) { /* never runs */ }'); + lines.push(''); + lines.push('// RIGHT — .unwrap() throws GraphQLRequestError on failure:'); + lines.push('const data = await db.model.findMany({...}).unwrap();'); + lines.push(''); + lines.push('// RIGHT — check .ok for control flow:'); + lines.push('const result = await db.model.findMany({...}).execute();'); + lines.push('if (!result.ok) { console.error(result.errors); return; }'); + lines.push('return result.data;'); + lines.push('```'); + lines.push(''); + lines.push('Available helpers on QueryBuilder (call **instead of** `.execute()`):'); + lines.push('- `.unwrap()` — throws on error, returns typed data'); + lines.push('- `.unwrapOr(default)` — returns default value on error'); + lines.push('- `.unwrapOrElse(fn)` — calls callback with errors on failure'); + lines.push(''); + lines.push('## Resources'); lines.push(''); lines.push(`- **Full API reference:** [README.md](./README.md) — model docs for all ${tableCount} tables`); @@ -203,7 +227,7 @@ export function generateOrmAgentsDocs( lines.push(''); lines.push('- Access models via `db.` (e.g. `db.User`)'); lines.push('- CRUD methods: `findMany`, `findOne`, `create`, `update`, `delete`'); - lines.push('- Always call `.execute()` to run the query'); + lines.push('- Call `.unwrap()` to run and throw on error, or `.execute()` for discriminated union result'); lines.push('- Custom operations via `db.query.` or `db.mutation.`'); lines.push(''); From 629c736eaf2a413a8a393e44a181f7ed646a396d Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Tue, 31 Mar 2026 08:05:10 +0000 Subject: [PATCH 2/2] fix: use .execute().unwrap() chaining pattern in generated AGENTS.md --- .../codegen/src/core/codegen/orm/docs-generator.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/graphql/codegen/src/core/codegen/orm/docs-generator.ts b/graphql/codegen/src/core/codegen/orm/docs-generator.ts index 5a204c4cc..fe2827329 100644 --- a/graphql/codegen/src/core/codegen/orm/docs-generator.ts +++ b/graphql/codegen/src/core/codegen/orm/docs-generator.ts @@ -201,8 +201,8 @@ export function generateOrmAgentsDocs( lines.push('// WRONG — errors are silently lost:'); lines.push('try { const r = await db.model.findMany({...}).execute(); } catch (e) { /* never runs */ }'); lines.push(''); - lines.push('// RIGHT — .unwrap() throws GraphQLRequestError on failure:'); - lines.push('const data = await db.model.findMany({...}).unwrap();'); + lines.push('// RIGHT — .execute().unwrap() throws GraphQLRequestError on failure:'); + lines.push('const data = await db.model.findMany({...}).execute().unwrap();'); lines.push(''); lines.push('// RIGHT — check .ok for control flow:'); lines.push('const result = await db.model.findMany({...}).execute();'); @@ -210,10 +210,10 @@ export function generateOrmAgentsDocs( lines.push('return result.data;'); lines.push('```'); lines.push(''); - lines.push('Available helpers on QueryBuilder (call **instead of** `.execute()`):'); - lines.push('- `.unwrap()` — throws on error, returns typed data'); - lines.push('- `.unwrapOr(default)` — returns default value on error'); - lines.push('- `.unwrapOrElse(fn)` — calls callback with errors on failure'); + lines.push('Available helpers (chain after `.execute()`):'); + lines.push('- `.execute().unwrap()` — throws on error, returns typed data'); + lines.push('- `.execute().unwrapOr(default)` — returns default value on error'); + lines.push('- `.execute().unwrapOrElse(fn)` — calls callback with errors on failure'); lines.push(''); lines.push('## Resources'); @@ -227,7 +227,7 @@ export function generateOrmAgentsDocs( lines.push(''); lines.push('- Access models via `db.` (e.g. `db.User`)'); lines.push('- CRUD methods: `findMany`, `findOne`, `create`, `update`, `delete`'); - lines.push('- Call `.unwrap()` to run and throw on error, or `.execute()` for discriminated union result'); + lines.push('- Chain `.execute().unwrap()` to run and throw on error, or `.execute()` alone for discriminated union result'); lines.push('- Custom operations via `db.query.` or `db.mutation.`'); lines.push('');