@stacksjs/error-handling 0.75.15 → 0.75.17
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/bughq.d.ts +11 -0
- package/dist/bughq.js +1 -0
- package/dist/handler.d.ts +2 -9
- package/dist/handler.js +3 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/dist/reporters.d.ts +15 -0
- package/dist/reporters.js +3 -0
- package/package.json +8 -7
package/dist/bughq.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BugHqMonitoringOptions, ErrorReporter } from '@stacksjs/types';
|
|
2
|
+
/**
|
|
3
|
+
* Create the BugHQ reporter used by `config/monitoring.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Error paths only enqueue through the SDK. Network failures stay inside the
|
|
6
|
+
* client, and the framework drains its in-flight requests through `log.flush()`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createBugHqReporter(options: CreateBugHqReporterOptions): ErrorReporter | null;
|
|
9
|
+
export declare interface CreateBugHqReporterOptions extends BugHqMonitoringOptions {
|
|
10
|
+
environment: string
|
|
11
|
+
}
|
package/dist/bughq.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BugHQClient}from"@bughq/sdk";export function createBugHqReporter(options){const key=options.key?.trim(),dsn=options.dsn?.trim();if(!key&&!dsn)return null;const client=new BugHQClient({key:key||void 0,dsn:dsn||void 0,host:options.host?.trim()||void 0,project:options.project?.trim()||void 0,release:options.release?.trim()||void 0,environment:options.environment,enabled:options.enabled,sampleRate:options.sampleRate,dedupeMs:options.dedupeMs,maxRetries:options.maxRetries,framework:"stacks",sdkName:"bughq.stacks",userAgent:"@stacksjs/error-handling (+server; Bun)",autoInstrument:!1,captureUnhandled:!1,heartbeat:!1});return{name:"bughq",report(event){client.captureException(event.error,event.context)},async flush(){await client.flush(options.flushTimeout)}}}
|
package/dist/handler.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from '@stacksjs/path';
|
|
2
|
+
import type { ErrorReportContext } from '@stacksjs/types';
|
|
2
3
|
import type { LogErrorOptions } from '@stacksjs/logging';
|
|
3
4
|
// Function to update the default log path when config is available
|
|
4
5
|
export declare function setLogPath(path: string): void;
|
|
@@ -7,15 +8,7 @@ export declare function handleError(err: string | Error | object | unknown, opti
|
|
|
7
8
|
/**
|
|
8
9
|
* Context information attached to errors for better debugging.
|
|
9
10
|
*/
|
|
10
|
-
export declare interface ErrorContext {
|
|
11
|
-
requestId?: string
|
|
12
|
-
url?: string
|
|
13
|
-
method?: string
|
|
14
|
-
userId?: string | number
|
|
15
|
-
ip?: string
|
|
16
|
-
userAgent?: string
|
|
17
|
-
[key: string]: unknown
|
|
18
|
-
}
|
|
11
|
+
export declare interface ErrorContext extends ErrorReportContext {}
|
|
19
12
|
declare interface WriteOptions {
|
|
20
13
|
logFile?: string
|
|
21
14
|
}
|
package/dist/handler.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import fs from"node:fs";import{dirname}from"node:path";import*as process from"node:process";function italic(str){return`\x1B[3m${str}\x1B[23m`}function stripAnsi(str){return str.replace(/\x1B\[[0-9;]*m/g,"")}import*as path from"@stacksjs/path";import{ExitCode}from"@stacksjs/types/exit-code";export class ErrorHandler{static isTestEnvironment=!1;static shouldExitProcess=!1;static handle(err,options){if(!this.isTestEnvironment)this.shouldExitProcess=options?.shouldExit===!0;if(options?.silent!==!0)this.writeErrorToConsole(err);let errorMessage;if(options?.message)errorMessage=options.message;else if(err instanceof Error)errorMessage=err.message;else if(typeof err==="string")errorMessage=err;else errorMessage=JSON.stringify(err);const error=err instanceof Error&&errorMessage===err.message?err:Error(errorMessage,err instanceof Error?{cause:err.cause??err}:void 0);if(err instanceof Error&&error!==err){Object.assign(error,err);if(err.stack)error.stack=`${error.name}: ${errorMessage}
|
|
1
|
+
import fs from"node:fs";import{dirname}from"node:path";import*as process from"node:process";function italic(str){return`\x1B[3m${str}\x1B[23m`}function stripAnsi(str){return str.replace(/\x1B\[[0-9;]*m/g,"")}import*as path from"@stacksjs/path";import{ExitCode}from"@stacksjs/types/exit-code";import{captureError}from"./reporters";export class ErrorHandler{static isTestEnvironment=!1;static shouldExitProcess=!1;static handle(err,options){if(!this.isTestEnvironment)this.shouldExitProcess=options?.shouldExit===!0;if(options?.silent!==!0)this.writeErrorToConsole(err);let errorMessage;if(options?.message)errorMessage=options.message;else if(err instanceof Error)errorMessage=err.message;else if(typeof err==="string")errorMessage=err;else errorMessage=JSON.stringify(err);const error=err instanceof Error&&errorMessage===err.message?err:Error(errorMessage,err instanceof Error?{cause:err.cause??err}:void 0);if(err instanceof Error&&error!==err){Object.assign(error,err);if(err.stack)error.stack=`${error.name}: ${errorMessage}
|
|
2
2
|
${err.stack.split(`
|
|
3
3
|
`).slice(1).join(`
|
|
4
|
-
`)}`}this.writeErrorToFile(error).catch((e)=>console.error(e));return error}static handleError(err,options){this.handle(err,options);return err}static async writeErrorToFile(err,context){if(!(err instanceof Error)){console.error("Error is not an instance of Error:",err);return}const contextStr=context?` | url=${context.url||"N/A"} method=${context.method||"N/A"} user=${context.userId||"anonymous"}`:"",stackLine=err.stack?`
|
|
4
|
+
`)}`}captureError(error);this.writeErrorToFile(error).catch((e)=>console.error(e));return error}static handleError(err,options){this.handle(err,options);return err}static async writeErrorToFile(err,context){if(!(err instanceof Error)){console.error("Error is not an instance of Error:",err);return}const contextStr=context?` | url=${context.url||"N/A"} method=${context.method||"N/A"} user=${context.userId||"anonymous"}`:"",stackLine=err.stack?`
|
|
5
5
|
${err.stack.split(`
|
|
6
6
|
`).slice(1,4).join(`
|
|
7
7
|
`)}`:"",formattedError=`[${new Date().toISOString()}] ${err.name}: ${err.message}${contextStr}${stackLine}
|
|
@@ -11,4 +11,4 @@ Context: ${JSON.stringify(serializableContext(contextData),null,2)}`;if(cause?.s
|
|
|
11
11
|
Caused by: ${stripAnsi(cause.stack)}`;writeToLogFile(logMessage).catch((err)=>{console.error("Failed to write error log:",err)});const error=cause?Error(errorMessage,{cause}):Error(errorMessage);if(err instanceof Error)Object.assign(error,err);if(cause?.stack)error.stack=`${error.name}: ${errorMessage}
|
|
12
12
|
${cause.stack.split(`
|
|
13
13
|
`).slice(1).join(`
|
|
14
|
-
`)}`;return ErrorHandler.handle(error,errorOptions)}
|
|
14
|
+
`)}`;if(contextData)captureError(error,contextData);return ErrorHandler.handle(error,errorOptions)}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,9 +22,11 @@ export type {
|
|
|
22
22
|
StackFrame,
|
|
23
23
|
UserContext,
|
|
24
24
|
} from './error-page';
|
|
25
|
+
export * from './bughq';
|
|
25
26
|
export * from './handler';
|
|
26
27
|
export * from './http';
|
|
27
28
|
export * from './model';
|
|
29
|
+
export * from './reporters';
|
|
28
30
|
export * from './utils';
|
|
29
31
|
export {
|
|
30
32
|
err,
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./handler";export*from"./http";export*from"./model";export*from"./utils";export{err,fromPromise,ok}from"ts-error-handling";export{ERROR_ILLUSTRATIONS,errorIllustration,illustrationForStatus}from"./error-illustrations";export{createErrorHandler,ERROR_PAGE_CSS,ErrorPageHandler,errorResponse,HTTP_ERRORS,renderError,renderErrorPage,renderHttpErrorHints,renderProductionErrorPage}from"./error-page";
|
|
1
|
+
export*from"./bughq";export*from"./handler";export*from"./http";export*from"./model";export*from"./reporters";export*from"./utils";export{err,fromPromise,ok}from"ts-error-handling";export{ERROR_ILLUSTRATIONS,errorIllustration,illustrationForStatus}from"./error-illustrations";export{createErrorHandler,ERROR_PAGE_CSS,ErrorPageHandler,errorResponse,HTTP_ERRORS,renderError,renderErrorPage,renderHttpErrorHints,renderProductionErrorPage}from"./error-page";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ErrorReportContext, ErrorReporter } from '@stacksjs/types';
|
|
2
|
+
/** Attach a reporter and return a function that detaches it. */
|
|
3
|
+
export declare function registerErrorReporter(reporter: ErrorReporter): () => void;
|
|
4
|
+
/** A copy of the reporters attached to this process. */
|
|
5
|
+
export declare function reporters(): readonly ErrorReporter[];
|
|
6
|
+
/**
|
|
7
|
+
* Deliver one exception without ever throwing back onto its handling path.
|
|
8
|
+
*
|
|
9
|
+
* Error identity is the deduplication key. The same exception may pass through
|
|
10
|
+
* an action boundary, the router boundary, and a process boundary, but it is
|
|
11
|
+
* still one failure and each reporter receives it once.
|
|
12
|
+
*/
|
|
13
|
+
export declare function captureError(value: unknown, context?: ErrorReportContext): Error;
|
|
14
|
+
/** Drain every buffering reporter without turning shutdown into a failure. */
|
|
15
|
+
export declare function flushErrorReporters(): Promise<void>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import process from"node:process";const registered=[],reported=new WeakSet,broken=new WeakSet,configuredSeen=new Set,CONFIG_OVERRIDES_KEY=Symbol.for("@stacksjs/config:overrides");function attachConfiguredReporters(){const configured=globalThis[CONFIG_OVERRIDES_KEY]?.monitoring?.reporters;if(!Array.isArray(configured))return;for(const reporter of configured){if(configuredSeen.has(reporter))continue;configuredSeen.add(reporter);if(!registered.includes(reporter))registerErrorReporter(reporter)}}function asError(value){if(value instanceof Error)return value;if(typeof value==="string")return Error(value);try{return Error(JSON.stringify(value))}catch{return Error(String(value))}}export function registerErrorReporter(reporter){if(!reporter||typeof reporter.name!=="string"||!reporter.name||typeof reporter.report!=="function"){process.stderr.write(`[error-reporting] Ignoring a reporter without a name and report() function.
|
|
2
|
+
`);return()=>{}}registered.push(reporter);return()=>{const at=registered.indexOf(reporter);if(at!==-1)registered.splice(at,1)}}export function reporters(){attachConfiguredReporters();return[...registered]}export function captureError(value,context){attachConfiguredReporters();const error=asError(value);if(registered.length===0||reported.has(error))return error;reported.add(error);const event={error,...context?{context}:{}};for(const reporter of registered)try{reporter.report(event)}catch(cause){if(broken.has(reporter))continue;broken.add(reporter);const reason=cause instanceof Error?cause.message:String(cause);process.stderr.write(`[error-reporting] Reporter "${reporter.name}" threw: ${reason}. Further throws from it are silent.
|
|
3
|
+
`)}return error}export async function flushErrorReporters(){attachConfiguredReporters();const pending=registered.filter((reporter)=>typeof reporter.flush==="function").map((reporter)=>Promise.resolve().then(()=>reporter.flush()));if(pending.length>0)await Promise.allSettled(pending)}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/error-handling",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.75.
|
|
4
|
+
"version": "0.75.17",
|
|
5
5
|
"description": "Type safe error handling.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": [
|
|
@@ -57,16 +57,17 @@
|
|
|
57
57
|
"prepublishOnly": "bun run build"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"@stacksjs/
|
|
62
|
-
"@stacksjs/
|
|
60
|
+
"@bughq/sdk": "^0.2.2",
|
|
61
|
+
"@stacksjs/path": "0.75.17",
|
|
62
|
+
"@stacksjs/stx": "^0.2.324",
|
|
63
|
+
"@stacksjs/types": "0.75.17",
|
|
63
64
|
"ts-error-handling": "^0.1.1",
|
|
64
65
|
"ts-syntax-highlighter": "^0.2.1"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
|
-
"@stacksjs/cli": "0.75.
|
|
68
|
-
"@stacksjs/config": "0.75.
|
|
69
|
-
"@stacksjs/validation": "0.75.
|
|
68
|
+
"@stacksjs/cli": "0.75.17",
|
|
69
|
+
"@stacksjs/config": "0.75.17",
|
|
70
|
+
"@stacksjs/validation": "0.75.17",
|
|
70
71
|
"better-dx": "^0.2.24"
|
|
71
72
|
},
|
|
72
73
|
"sideEffects": false
|