@webpieces/rules-config 0.4.762 → 0.4.763

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/rules-config",
3
- "version": "0.4.762",
3
+ "version": "0.4.763",
4
4
  "description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -112,7 +112,7 @@ TraceId (also called correlation ID, request ID) ties these together.
112
112
  - Is it catching for cleanup? → Usually wrong pattern
113
113
  - **Is this a global entry point?** → **ASK USER**: "I think this code is the entry point where we need a global try-catch block. Is this correct?" (95% of the time it is NOT!)
114
114
  - **Is this edge code calling external services?** → **ASK USER**: "This looks like edge code calling an external service. Should I add request/response logging with try-catch?"
115
- - **Is this form error handling?** → Valid IF: catches only `HttpUserError` for display AND rethrows other errors (see Form Error Handling Pattern)
115
+ - **Is this form error handling?** → Valid IF: catches only `ApiEndUserError` for display AND rethrows other errors (see Form Error Handling Pattern)
116
116
  - Is it adding context to the error before rethrowing? → May be valid (see Problem 3)
117
117
 
118
118
  3. **IF REMOVING** the try-catch block:
@@ -232,7 +232,7 @@ export class DebugController implements DebugApi {
232
232
  async getErrorById(@PathParam('id') id: string): Promise<DebugErrorResponse> {
233
233
  const error = ErrorStore.get(id);
234
234
  if (!error) {
235
- throw new HttpNotFoundError(`Error ${id} not found`);
235
+ throw new ApiNotFoundError(`Error ${id} not found`);
236
236
  }
237
237
 
238
238
  return {
@@ -377,9 +377,10 @@ async function callVendorApiWithRetry(request: VendorRequest): Promise<VendorRes
377
377
 
378
378
  // After retries exhausted, throw with traceId
379
379
  const traceId = RequestContext.get<string>('TRACE_ID');
380
- throw new HttpVendorError(
380
+ throw new ApiDependencyBackoffError(
381
381
  `Vendor API failed after ${maxRetries} retries. TraceId: ${traceId}`,
382
- lastError
382
+ 30,
383
+ lastError,
383
384
  );
384
385
  }
385
386
  ```
@@ -479,7 +480,7 @@ You may use `// eslint-disable-next-line @webpieces/no-unmanaged-exceptions` ONL
479
480
  3. **Resource cleanup** with explicit approval
480
481
  4. **Global error handler entry points** (see below)
481
482
  5. **Edge code patterns** for vendor/external service calls (see below)
482
- 6. **Form error handling** - catching `HttpUserError` for display, rethrowing others (see below)
483
+ 6. **Form error handling** - catching `ApiEndUserError` for display, rethrowing others (see below)
483
484
 
484
485
  All require:
485
486
  - Comment explaining WHY try-catch is needed
@@ -615,9 +616,9 @@ async function sendMail(request: MailRequest): Promise<MailResponse> {
615
616
  Frontend forms often need to catch user-facing errors (like validation errors) to display in the UI, while rethrowing unexpected errors to the global handler.
616
617
 
617
618
  **This pattern is ACCEPTABLE because**:
618
- - It catches ONLY user-facing errors (`HttpUserError`) for display
619
+ - It catches ONLY user-facing errors (`ApiEndUserError`) for display
619
620
  - Unexpected errors are RETHROWN (not swallowed)
620
- - Server throws `HttpUserError` → protocol translates to error payload → client translates back to exception
621
+ - Server throws `ApiEndUserError` → protocol translates to error payload → client translates back to exception
621
622
 
622
623
  ### Example: Form Submission Error Handling
623
624
  ```typescript
@@ -629,7 +630,7 @@ async submitForm(): Promise<void> {
629
630
  } catch (err: unknown) {
630
631
  const error = toError(err);
631
632
 
632
- if (error instanceof HttpUserError) {
633
+ if (error instanceof ApiEndUserError) {
633
634
  // User-facing error - display in form
634
635
  this.formError = error.message;
635
636
  this.cdr.detectChanges();
@@ -645,31 +646,31 @@ async submitForm(): Promise<void> {
645
646
 
646
647
  1. **Selective catching**: Only catches errors meant for user display
647
648
  2. **No swallowing**: Unexpected errors bubble to global handler with traceId
648
- 3. **Protocol design**: Server intentionally throws `HttpUserError` for user-facing messages
649
+ 3. **Protocol design**: Server intentionally throws `ApiEndUserError` for user-facing messages
649
650
  4. **UX requirement**: Forms must show validation errors inline, not via global error page
650
651
 
651
652
  ### Key Requirements
652
653
 
653
- - **ONLY catch specific error types** (e.g., `HttpUserError`, `ValidationError`)
654
+ - **ONLY catch specific error types** (e.g., `ApiEndUserError`, `ValidationError`)
654
655
  - **ALWAYS rethrow** errors that aren't user-facing
655
- - Server-side code MUST throw `HttpUserError` for user-displayable messages
656
+ - Server-side code MUST throw `ApiEndUserError` for user-displayable messages
656
657
 
657
- ### `HttpUserError` is not a convention — it is the only message that survives the wire
658
+ ### `ApiEndUserError` is not a convention — it is the only message that survives the wire
658
659
 
659
- This is a HARD RULE, enforced by `HttpErrorWireMapper` on the server (`http-server`):
660
+ This is a HARD RULE, enforced by `ApiErrorHttpMapper` on the server (`http-server`):
660
661
 
661
- > **Only `HttpUserError`'s `message` is sent to the caller.** Every other `HttpError` subclass sends
662
- > the generic HTTP reason phrase for its status — `'Not Found'`, `'Internal Server Error'`, … — and
662
+ > **Only `ApiEndUserError`'s `message` is sent to the caller.** Every other `ApiError` subclass sends
663
+ > its generic semantic message — `'Not Found'`, `'Internal Error'`, … — and
663
664
  > its real message goes to the server's LOG only.
664
665
 
665
666
  `Error.message` is an operator-facing field. It routinely quotes a downstream service url, an HTTP
666
667
  method and content-type, a body snippet, a table name or an internal id, and none of that may reach an
667
668
  external consumer. So:
668
669
 
669
- - Throwing `new HttpBadRequestError('the email you entered is already taken')` does **not** show that
670
- text to the user — the caller receives `'Bad Request'`. Throw `HttpUserError` instead, or pass the
671
- text as `HttpBadRequestError`'s `guiMessage`, which IS sent (as `guiAlertMessage`).
672
- - A client must branch on the error TYPE, on `subType`, on `errorCode` or on `guiAlertMessage` — never
670
+ - Throwing `new ApiBadRequestError('the email you entered is already taken')` does **not** show that
671
+ text to the user — the caller receives `'Bad Request'`. Throw `ApiEndUserError` instead, or pass the
672
+ text as `ApiBadRequestError`'s `callerMessage`, which IS sent (as `callerMessage`).
673
+ - A client must branch on the error TYPE, on `subType`, on `errorCode` or on `callerMessage` — never
673
674
  on the prose of `message`. Against a current webpieces server that prose is a constant per status.
674
675
  - An app that deliberately wants to publish richer text installs an `ErrorTranslators` on
675
676
  `ClientRegistry` (`setErrorTranslators`); its `toWire()` response — status, reason phrase, headers
@@ -754,7 +755,6 @@ and in `/debugLocal/{traceId}` responses.
754
755
  2. **Edge code**: External API calls, database operations, email services - use logRequest/logSuccess/logFailure pattern
755
756
  3. **Retry loops**: Vendor APIs with exponential backoff
756
757
  4. **Batching**: Partial failure handling where processing must continue
757
- 5. **Form error handling**: Catch `HttpUserError` for UI display, rethrow all other errors
758
+ 5. **Form error handling**: Catch `ApiEndUserError` for UI display, rethrow all other errors
758
759
 
759
760
  **Remember**: If you can't handle the error meaningfully, don't catch it. Let it bubble to the global handler where it will be logged with full context and traceId.
760
-