@rebasepro/server-postgres 0.11.1-canary.gfd39654 → 0.12.0
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/dist/PostgresBootstrapper.d.ts +8 -0
- package/dist/collections/buildRegistry.d.ts +1 -1
- package/dist/{ensure-collection-tables-DGMYK0fr.js → ensure-collection-tables-CNTcZGvn.js} +3 -3
- package/dist/{ensure-collection-tables-DGMYK0fr.js.map → ensure-collection-tables-CNTcZGvn.js.map} +1 -1
- package/dist/history/HistoryService.d.ts +9 -29
- package/dist/index.es.js +397 -53
- package/dist/index.es.js.map +1 -1
- package/dist/schema/dynamic-tables.d.ts +1 -1
- package/dist/schema/introspect-runtime.d.ts +1 -1
- package/dist/services/FetchService.d.ts +36 -1
- package/dist/services/row-pipeline.d.ts +3 -1
- package/dist/{src-3VmUJ8Xn.js → src-BbFOPJ1S.js} +197 -18
- package/dist/src-BbFOPJ1S.js.map +1 -0
- package/dist/{src-D5xBTl32.js → src-Zqwaw3P5.js} +136 -90
- package/dist/src-Zqwaw3P5.js.map +1 -0
- package/dist/utils/drizzle-conditions.d.ts +157 -3
- package/dist/utils/pg-error-utils.d.ts +6 -3
- package/package.json +6 -6
- package/src/PostgresBootstrapper.ts +23 -6
- package/src/collections/buildRegistry.ts +1 -1
- package/src/history/HistoryService.ts +13 -31
- package/src/schema/dynamic-tables.ts +1 -1
- package/src/schema/generate-drizzle-schema-logic.ts +10 -2
- package/src/schema/introspect-runtime.ts +1 -1
- package/src/services/FetchService.ts +79 -11
- package/src/services/row-pipeline.ts +3 -1
- package/src/utils/drizzle-conditions.ts +509 -45
- package/src/utils/pg-error-utils.ts +52 -3
- package/dist/src-3VmUJ8Xn.js.map +0 -1
- package/dist/src-D5xBTl32.js.map +0 -1
|
@@ -9,6 +9,35 @@
|
|
|
9
9
|
|
|
10
10
|
import { logger } from "@rebasepro/server";
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Shape of a deliberate client-facing error — `ApiError` from
|
|
14
|
+
* `@rebasepro/server`, or anything else carrying a 4xx `statusCode`.
|
|
15
|
+
*
|
|
16
|
+
* Matched structurally rather than with `instanceof`: `@rebasepro/server` can
|
|
17
|
+
* be loaded twice (published dist vs. workspace source), which breaks class
|
|
18
|
+
* identity — `PersistService` hedges against the same thing by also accepting
|
|
19
|
+
* `name === "ApiError"`.
|
|
20
|
+
*/
|
|
21
|
+
interface ClientFacingError extends Error {
|
|
22
|
+
statusCode?: number;
|
|
23
|
+
code?: string;
|
|
24
|
+
/** See `ApiError.expected` — routine outcomes log at debug, not warn. */
|
|
25
|
+
expected?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Return the error when it is a deliberate 4xx, otherwise null.
|
|
30
|
+
*
|
|
31
|
+
* A thrown `ApiError` is a decision the server made about the request, not a
|
|
32
|
+
* database failure: its message and code are already written for the client.
|
|
33
|
+
*/
|
|
34
|
+
function asClientFacingError(error: unknown): ClientFacingError | null {
|
|
35
|
+
if (!(error instanceof Error)) return null;
|
|
36
|
+
const e = error as ClientFacingError;
|
|
37
|
+
if (typeof e.statusCode !== "number" || e.statusCode < 400 || e.statusCode >= 500) return null;
|
|
38
|
+
return e;
|
|
39
|
+
}
|
|
40
|
+
|
|
12
41
|
/** Shape of PostgreSQL errors with diagnostic metadata. */
|
|
13
42
|
export interface PostgresError extends Error {
|
|
14
43
|
code?: string;
|
|
@@ -180,14 +209,34 @@ export function pgErrorToFriendlyMessage(pgError: PostgresError, context: string
|
|
|
180
209
|
/**
|
|
181
210
|
* Sanitize any error into a message safe and helpful for the client.
|
|
182
211
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
212
|
+
* A deliberate 4xx (`ApiError`) passes through untouched — the server already
|
|
213
|
+
* decided what the client should read. Otherwise the PG error is extracted
|
|
214
|
+
* from the Drizzle cause chain, falling back to a generic message that
|
|
215
|
+
* doesn't leak SQL.
|
|
185
216
|
*
|
|
186
217
|
* @param error - The raw caught error
|
|
187
218
|
* @param context - A human-readable context string (e.g. collection path)
|
|
188
|
-
* @returns An object with `message` (user-friendly) and optional `code`
|
|
219
|
+
* @returns An object with `message` (user-friendly) and optional `code`
|
|
220
|
+
* (the `ApiError` code, or the PG SQLSTATE).
|
|
189
221
|
*/
|
|
190
222
|
export function sanitizeErrorForClient(error: unknown, context: string): { message: string; code?: string } {
|
|
223
|
+
// ── A deliberate 4xx is not a database failure ──────────────────
|
|
224
|
+
// Its message and code are written for the client; replacing them with
|
|
225
|
+
// "Check server logs" would discard the only diagnosis the caller gets
|
|
226
|
+
// (e.g. the offending filter field and the collection's valid ones).
|
|
227
|
+
// Log level follows the same convention as the HTTP error handler in
|
|
228
|
+
// @rebasepro/server: routine outcomes at debug, everything else at warn.
|
|
229
|
+
const clientError = asClientFacingError(error);
|
|
230
|
+
if (clientError) {
|
|
231
|
+
const line = `[API ${clientError.statusCode} ${clientError.code ?? "BAD_REQUEST"}] in "${context}": ${clientError.message}`;
|
|
232
|
+
if (clientError.expected) {
|
|
233
|
+
logger.debug(line);
|
|
234
|
+
} else {
|
|
235
|
+
logger.warn(`⚠️ ${line}`);
|
|
236
|
+
}
|
|
237
|
+
return { message: clientError.message, ...(clientError.code && { code: clientError.code }) };
|
|
238
|
+
}
|
|
239
|
+
|
|
191
240
|
// ── Always log the full, unsanitized error server-side ──────────
|
|
192
241
|
const pgError = extractPgError(error);
|
|
193
242
|
|