Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions graphql/codegen/src/client/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
* Re-export error handling utilities from @constructive-io/graphql-query.
*/
export {
DataError,
DataErrorType,
PG_ERROR_CODES,
ConstructiveError,
classify,
createError,
format,
isConstructiveError,
isPublicCode,
isPublicError,
isRetryable,
parse,
parseGraphQLError,
isDataError,
type DataErrorOptions,
toError,
type ErrorClass,
type ErrorContext,
type GraphQLError,
type ParsedError,
} from '@constructive-io/graphql-query';
17 changes: 12 additions & 5 deletions graphql/codegen/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
*/

export {
classify,
ConstructiveError,
createError,
DataError,
type DataErrorOptions,
DataErrorType,
type ErrorClass,
type ErrorContext,
format,
type GraphQLError,
isDataError,
isConstructiveError,
isPublicCode,
isPublicError,
isRetryable,
parse,
type ParsedError,
parseGraphQLError,
PG_ERROR_CODES,
toError,
} from './error';
export {
createGraphQLClient,
Expand Down
32 changes: 24 additions & 8 deletions graphql/query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This package is the **canonical source** for PostGraphile query generation logic
- **Mutation generators** — `buildPostGraphileCreate`, `buildPostGraphileUpdate`, `buildPostGraphileDelete`
- **Introspection pipeline** — `inferTablesFromIntrospection` to convert a GraphQL schema into `CleanTable` metadata
- **AST builders** — low-level `getAll`, `getMany`, `getOne`, `createOne`, `patchOne`, `deleteOne`
- **Client utilities** — `TypedDocumentString`, `execute`, `DataError` for type-safe execution and error handling
- **Client utilities** — `TypedDocumentString`, `execute`, and `@constructive-io/errors` re-exports (`ConstructiveError`, `parseGraphQLError`) for type-safe execution and error handling
- **Naming helpers** — server-aware inflection functions that respect PostGraphile's schema naming

All modules are **browser-safe** (no Node.js APIs). `@constructive-io/graphql-codegen` depends on this package for the core logic and adds Node.js-only features (CLI, file output, watch mode).
Expand Down Expand Up @@ -329,20 +329,36 @@ const { data, errors } = await client.execute(query, {

## Error Handling

Error handling is backed by [`@constructive-io/errors`](../../packages/errors), the
single source of truth for error codes, their public/internal class, message
copy (i18n), and cross-source parsing. There is no separate client-side error
catalog or message string-matching — the client re-exports the canonical
`ConstructiveError`, `parse`, `format`, and helpers.

```ts
import { DataError, parseGraphQLError, DataErrorType } from '@constructive-io/graphql-query';
import {
ConstructiveError,
parseGraphQLError,
format,
isRetryable,
} from '@constructive-io/graphql-query';

try {
const result = await client.execute(createQuery, { input: { user: { name: 'Alice' } } });
if (result.errors) {
// Normalize any error into a ConstructiveError (machine code + context + class).
const error = parseGraphQLError(result.errors[0]);
if (error.type === DataErrorType.UNIQUE_VIOLATION) {
console.log('Duplicate entry:', error.constraintName);
if (error.code === 'UNIQUE_VIOLATION') {
console.log('Duplicate entry:', error.context.constraint);
}
}
} catch (err) {
if (err instanceof DataError) {
console.log(err.type, err.message);
if (err instanceof ConstructiveError) {
// Localized, user-facing copy for public codes; retry hint for transport errors.
console.log(err.code, format(err.code, err.context));
if (isRetryable(err)) {
// network/timeout/rate-limit — safe to retry
}
}
}
```
Expand Down Expand Up @@ -441,8 +457,8 @@ GraphQL Schema (introspection or _meta)
| `TypedDocumentString` | Type-safe GraphQL document wrapper (compatible with codegen client) |
| `createGraphQLClient(options)` | Create a typed GraphQL client |
| `execute(url, query, variables, options?)` | Execute a GraphQL query |
| `DataError` | Structured error class with PG SQLSTATE classification |
| `parseGraphQLError(error)` | Parse raw GraphQL error into `DataError` |
| `ConstructiveError` | Canonical error class (`code`, `context`, `class`, `http`) from `@constructive-io/errors` |
| `parseGraphQLError(error)` | Parse any error (pg / GraphQL / message / SQLSTATE) into a `ConstructiveError` |

### Naming Helpers

Expand Down
1 change: 1 addition & 0 deletions graphql/query/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
},
"dependencies": {
"@0no-co/graphql.web": "^1.1.2",
"@constructive-io/errors": "workspace:^",
"@constructive-io/fetch": "^1.1.1",
"@constructive-io/graphql-types": "workspace:^",
"ajv": "^8.20.0",
Expand Down
Loading
Loading