style: auto-format codebase with Prettier

Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
This commit is contained in:
Wuesteon 2025-11-27 18:33:16 +01:00
parent 0241f5554c
commit d36b321d9d
3952 changed files with 661498 additions and 739751 deletions

View file

@ -1,26 +1,22 @@
import {
ErrorCode,
ERROR_CODE_TO_HTTP_STATUS,
ERROR_CODE_RETRYABLE,
} from '../types/error-codes';
import { ErrorCode, ERROR_CODE_TO_HTTP_STATUS, ERROR_CODE_RETRYABLE } from '../types/error-codes';
/**
* Additional context that can be attached to errors.
*/
export interface ErrorContext {
[key: string]: unknown;
[key: string]: unknown;
}
/**
* Options for creating an AppError.
*/
export interface AppErrorOptions {
code: ErrorCode;
message: string;
cause?: Error | AppError;
context?: ErrorContext;
httpStatus?: number;
retryable?: boolean;
code: ErrorCode;
message: string;
cause?: Error | AppError;
context?: ErrorContext;
httpStatus?: number;
retryable?: boolean;
}
/**
@ -50,130 +46,126 @@ export interface AppErrorOptions {
* ```
*/
export class AppError extends Error {
/** Standardized error code */
readonly code: ErrorCode;
/** Standardized error code */
readonly code: ErrorCode;
/** HTTP status code for API responses */
readonly httpStatus: number;
/** HTTP status code for API responses */
readonly httpStatus: number;
/** Whether the operation can be retried */
readonly retryable: boolean;
/** Whether the operation can be retried */
readonly retryable: boolean;
/** Original error that caused this error (for wrapping) */
readonly cause?: Error | AppError;
/** Original error that caused this error (for wrapping) */
readonly cause?: Error | AppError;
/** Additional context information */
readonly context: ErrorContext;
/** Additional context information */
readonly context: ErrorContext;
/** Timestamp when error was created */
readonly timestamp: string;
/** Timestamp when error was created */
readonly timestamp: string;
constructor(options: AppErrorOptions) {
super(options.message);
this.name = 'AppError';
this.code = options.code;
this.cause = options.cause;
this.context = options.context ?? {};
this.timestamp = new Date().toISOString();
constructor(options: AppErrorOptions) {
super(options.message);
this.name = 'AppError';
this.code = options.code;
this.cause = options.cause;
this.context = options.context ?? {};
this.timestamp = new Date().toISOString();
// Use provided values or defaults from mappings
this.httpStatus =
options.httpStatus ?? ERROR_CODE_TO_HTTP_STATUS[options.code];
this.retryable = options.retryable ?? ERROR_CODE_RETRYABLE[options.code];
// Use provided values or defaults from mappings
this.httpStatus = options.httpStatus ?? ERROR_CODE_TO_HTTP_STATUS[options.code];
this.retryable = options.retryable ?? ERROR_CODE_RETRYABLE[options.code];
// Capture stack trace
Error.captureStackTrace(this, this.constructor);
}
// Capture stack trace
Error.captureStackTrace(this, this.constructor);
}
/**
* Create a wrapped error with additional context.
* Similar to Go's `fmt.Errorf("context: %w", err)`.
*
* @param contextMessage - Description of the operation that failed
* @param additionalContext - Extra context data to include
* @returns A new AppError with the original as its cause
*
* @example
* ```typescript
* const wrapped = originalError.wrap('fetching user data');
* // Message: "fetching user data: original message"
* ```
*/
wrap(contextMessage: string, additionalContext?: ErrorContext): AppError {
return new AppError({
code: this.code,
message: `${contextMessage}: ${this.message}`,
cause: this,
context: { ...this.context, ...additionalContext },
httpStatus: this.httpStatus,
retryable: this.retryable,
});
}
/**
* Create a wrapped error with additional context.
* Similar to Go's `fmt.Errorf("context: %w", err)`.
*
* @param contextMessage - Description of the operation that failed
* @param additionalContext - Extra context data to include
* @returns A new AppError with the original as its cause
*
* @example
* ```typescript
* const wrapped = originalError.wrap('fetching user data');
* // Message: "fetching user data: original message"
* ```
*/
wrap(contextMessage: string, additionalContext?: ErrorContext): AppError {
return new AppError({
code: this.code,
message: `${contextMessage}: ${this.message}`,
cause: this,
context: { ...this.context, ...additionalContext },
httpStatus: this.httpStatus,
retryable: this.retryable,
});
}
/**
* Get the root cause of the error chain.
* Traverses the cause chain to find the original error.
*/
rootCause(): Error {
let current: Error = this;
while (current instanceof AppError && current.cause) {
current = current.cause;
}
return current;
}
/**
* Get the root cause of the error chain.
* Traverses the cause chain to find the original error.
*/
rootCause(): Error {
let current: Error = this;
while (current instanceof AppError && current.cause) {
current = current.cause;
}
return current;
}
/**
* Check if this error or any in the chain has the given code.
* Similar to Go's `errors.Is()`.
*
* @param code - The error code to check for
* @returns true if this error or any cause has the given code
*
* @example
* ```typescript
* if (error.hasCode(ErrorCode.INSUFFICIENT_CREDITS)) {
* // Show upgrade prompt
* }
* ```
*/
hasCode(code: ErrorCode): boolean {
let current: Error | undefined = this;
while (current) {
if (current instanceof AppError && current.code === code) {
return true;
}
current = current instanceof AppError ? current.cause : undefined;
}
return false;
}
/**
* Check if this error or any in the chain has the given code.
* Similar to Go's `errors.Is()`.
*
* @param code - The error code to check for
* @returns true if this error or any cause has the given code
*
* @example
* ```typescript
* if (error.hasCode(ErrorCode.INSUFFICIENT_CREDITS)) {
* // Show upgrade prompt
* }
* ```
*/
hasCode(code: ErrorCode): boolean {
let current: Error | undefined = this;
while (current) {
if (current instanceof AppError && current.code === code) {
return true;
}
current = current instanceof AppError ? current.cause : undefined;
}
return false;
}
/**
* Convert to JSON for API responses.
* Excludes stack traces and internal details.
*/
toJSON(): Record<string, unknown> {
return {
code: this.code,
message: this.message,
httpStatus: this.httpStatus,
retryable: this.retryable,
timestamp: this.timestamp,
...(Object.keys(this.context).length > 0 && { details: this.context }),
};
}
/**
* Convert to JSON for API responses.
* Excludes stack traces and internal details.
*/
toJSON(): Record<string, unknown> {
return {
code: this.code,
message: this.message,
httpStatus: this.httpStatus,
retryable: this.retryable,
timestamp: this.timestamp,
...(Object.keys(this.context).length > 0 && { details: this.context }),
};
}
/**
* Convert to full JSON including stack and cause (for logging).
* Use this for server-side logging, not client responses.
*/
toFullJSON(): Record<string, unknown> {
return {
...this.toJSON(),
stack: this.stack,
cause:
this.cause instanceof AppError
? this.cause.toFullJSON()
: this.cause?.message,
};
}
/**
* Convert to full JSON including stack and cause (for logging).
* Use this for server-side logging, not client responses.
*/
toFullJSON(): Record<string, unknown> {
return {
...this.toJSON(),
stack: this.stack,
cause: this.cause instanceof AppError ? this.cause.toFullJSON() : this.cause?.message,
};
}
}