@hkdigital/lib-core 0.3.14 → 0.4.3
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/README.md +18 -9
- package/dist/auth/errors.d.ts +1 -0
- package/dist/auth/errors.js +1 -0
- package/dist/{states → browser/navigation}/navigation.svelte.js +1 -1
- package/dist/browser/navigation.d.ts +1 -0
- package/dist/browser/navigation.js +1 -0
- package/dist/config/README.md +5 -5
- package/dist/config/generators/imagetools.d.ts +2 -0
- package/dist/config/generators/imagetools.js +23 -10
- package/dist/config/generators/vite.js +1 -1
- package/dist/config/imagetools.d.ts +5 -5
- package/dist/config/typedef.d.ts +11 -0
- package/dist/config/typedef.js +17 -0
- package/dist/design/README.md +211 -66
- package/dist/design/config/{design-config.d.ts → design-tokens.d.ts} +23 -10
- package/dist/design/config/design-tokens.js +107 -0
- package/dist/design/generators/index.d.ts +51 -0
- package/dist/design/generators/index.js +124 -0
- package/dist/design/index.d.ts +3 -4
- package/dist/design/index.js +24 -41
- package/dist/design/plugins/skeleton.d.ts +4 -2
- package/dist/design/plugins/skeleton.js +3 -2
- package/dist/design/themes/hkdev/components/buttons/button-text.css +38 -25
- package/dist/design/themes/hkdev/theme-ext.js +1 -1
- package/dist/design/utils/clamp.js +1 -1
- package/dist/design/utils/root-vars.d.ts +50 -39
- package/dist/design/utils/root-vars.js +127 -29
- package/dist/{classes/data → generic/data/classes}/IterableTree.js +2 -2
- package/dist/{classes/data → generic/data/classes}/Selector.js +1 -1
- package/dist/generic/data/classes/typedef.d.ts +24 -0
- package/dist/generic/data/classes/typedef.js +14 -0
- package/dist/generic/data.d.ts +2 -0
- package/dist/generic/data.js +2 -0
- package/dist/generic/errors.d.ts +2 -0
- package/dist/generic/errors.js +2 -0
- package/dist/generic/events.d.ts +1 -0
- package/dist/generic/events.js +1 -0
- package/dist/{classes/promise → generic/promises/classes}/HkPromise.d.ts +17 -7
- package/dist/{classes/promise → generic/promises/classes}/HkPromise.js +20 -10
- package/dist/generic/promises.d.ts +1 -0
- package/dist/generic/promises.js +1 -0
- package/dist/{classes/streams → generic/streaming/classes}/ServerEventsStore.d.ts +1 -1
- package/dist/{classes/streams → generic/streaming/classes}/ServerEventsStore.js +2 -2
- package/dist/generic/streaming.d.ts +3 -0
- package/dist/generic/streaming.js +3 -0
- package/dist/generic/typedef.d.ts +1 -0
- package/dist/generic/typedef.js +1 -0
- package/dist/index.js +1 -0
- package/dist/logging/errors.d.ts +7 -0
- package/dist/logging/errors.js +11 -0
- package/dist/logging/index.d.ts +2 -3
- package/dist/logging/index.js +3 -4
- package/dist/logging/internal/adapters/console.d.ts +1 -16
- package/dist/logging/internal/adapters/console.js +322 -14
- package/dist/logging/internal/adapters/formatting.d.ts +69 -0
- package/dist/logging/internal/adapters/formatting.js +395 -0
- package/dist/logging/internal/adapters/pino.js +128 -27
- package/dist/logging/internal/adapters/typedef.d.ts +30 -0
- package/dist/logging/internal/adapters/typedef.js +11 -0
- package/dist/logging/internal/factories/client.js +1 -1
- package/dist/logging/internal/factories/server.js +12 -2
- package/dist/logging/internal/logger/Logger.d.ts +9 -7
- package/dist/logging/internal/logger/Logger.js +44 -9
- package/dist/logging/internal/test-errors.d.ts +35 -0
- package/dist/logging/internal/test-errors.js +137 -0
- package/dist/network/cache/IndexedDbCache.d.ts +1 -1
- package/dist/network/cache/MemoryResponseCache.d.ts +5 -0
- package/dist/network/cache/MemoryResponseCache.js +5 -2
- package/dist/network/errors.d.ts +2 -0
- package/dist/network/errors.js +2 -0
- package/dist/network/http/caching.js +1 -1
- package/dist/network/http/errors.d.ts +2 -2
- package/dist/network/http/errors.js +5 -13
- package/dist/network/http/http-request.js +1 -1
- package/dist/network/http/json-request.js +1 -1
- package/dist/network/http/response.js +1 -1
- package/dist/network/http/url.js +1 -1
- package/dist/network/loaders/README.md +14 -7
- package/dist/network/loaders/audio/AudioScene.svelte.js +3 -2
- package/dist/network/loaders/image/ImageLoader.svelte.d.ts +2 -2
- package/dist/network/loaders/image/ImageLoader.svelte.js +1 -1
- package/dist/network/loaders/image/ImageScene.svelte.d.ts +2 -2
- package/dist/network/loaders/image/ImageScene.svelte.js +9 -8
- package/dist/network/loaders/image/ImageVariantsLoader.svelte.d.ts +5 -5
- package/dist/network/loaders/image/ImageVariantsLoader.svelte.js +14 -13
- package/dist/network/loaders/image/utils/index.d.ts +2 -2
- package/dist/network/loaders/image/utils/index.js +9 -12
- package/dist/network/loaders/typedef.d.ts +0 -9
- package/dist/network/loaders/typedef.js +0 -12
- package/dist/network/states/NetworkLoader.svelte.d.ts +1 -1
- package/dist/network/states/NetworkLoader.svelte.js +3 -2
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.js +0 -3
- package/dist/services/service-base/ServiceBase.d.ts +2 -2
- package/dist/services/service-base/ServiceBase.js +15 -11
- package/dist/services/service-base/typedef.d.ts +2 -31
- package/dist/services/service-base/typedef.js +3 -2
- package/dist/services/service-manager/ServiceManager.d.ts +3 -3
- package/dist/services/service-manager/ServiceManager.js +2 -2
- package/dist/services/service-manager/typedef.d.ts +3 -3
- package/dist/services/service-manager/typedef.js +3 -3
- package/dist/services/typedef.d.ts +2 -0
- package/dist/services/typedef.js +2 -0
- package/dist/{classes/svelte → state/classes}/loading-state-machine/LoadingStateMachine.svelte.d.ts +1 -1
- package/dist/{classes/svelte → state/classes}/loading-state-machine/LoadingStateMachine.svelte.js +1 -1
- package/dist/state/classes/subscribers-count/index.d.ts +1 -0
- package/dist/state/classes/subscribers-count/index.js +1 -0
- package/dist/state/classes.d.ts +3 -0
- package/dist/state/classes.js +3 -0
- package/dist/{util/svelte/state-context/index.d.ts → state/context/state-context.d.ts} +1 -1
- package/dist/{util/svelte/state-context/index.js → state/context/state-context.js} +4 -4
- package/dist/state/context.d.ts +1 -0
- package/dist/state/context.js +1 -0
- package/dist/state/stores.d.ts +1 -0
- package/dist/state/stores.js +1 -0
- package/dist/ui/README.md +49 -0
- package/dist/ui/components/button-group/index.d.ts +1 -0
- package/dist/ui/components/button-group/index.js +1 -0
- package/dist/ui/{primitives → components}/drag-drop/DragDropContext.svelte +1 -1
- package/dist/ui/{primitives → components}/drag-drop/DragDropContext.svelte.d.ts +1 -1
- package/dist/ui/{primitives → components}/drag-drop/Draggable.svelte +2 -2
- package/dist/ui/{primitives → components}/drag-drop/Draggable.svelte.d.ts +1 -1
- package/dist/ui/{primitives → components}/drag-drop/DropZone.svelte +4 -4
- package/dist/ui/{primitives → components}/drag-drop/DropZone.svelte.d.ts +3 -3
- package/dist/ui/{primitives → components}/drag-drop/DropZoneArea.svelte +3 -3
- package/dist/ui/{primitives → components}/drag-drop/DropZoneArea.svelte.d.ts +4 -4
- package/dist/ui/{primitives → components}/drag-drop/DropZoneList.svelte +3 -3
- package/dist/ui/{primitives → components}/drag-drop/DropZoneList.svelte.d.ts +3 -3
- package/dist/ui/{primitives → components}/drag-drop/drag-state.svelte.d.ts +11 -11
- package/dist/ui/{primitives → components}/drag-drop/drag-state.svelte.js +5 -5
- package/dist/ui/components/drag-drop/typedef.d.ts +2 -0
- package/dist/ui/components/drag-drop/typedef.js +2 -0
- package/dist/ui/components/game-box/GameBox.svelte +1 -1
- package/dist/ui/components/game-box/index.d.ts +1 -0
- package/dist/ui/components/game-box/index.js +1 -0
- package/dist/ui/components/grid-layers/index.d.ts +1 -0
- package/dist/ui/components/grid-layers/index.js +1 -0
- package/dist/ui/{primitives/layout → components}/grid-layers/util.js +1 -1
- package/dist/ui/components/hk-app-layout/HkAppLayout.state.svelte.d.ts +3 -3
- package/dist/ui/components/hk-app-layout/HkAppLayout.state.svelte.js +3 -4
- package/dist/ui/components/hk-app-layout/index.d.ts +1 -0
- package/dist/ui/components/hk-app-layout/index.js +1 -0
- package/dist/ui/components/image-box/ImageBox.svelte +2 -2
- package/dist/ui/components/image-box/ImageBox.svelte.d.ts +3 -3
- package/dist/ui/components/image-box/index.d.ts +1 -1
- package/dist/ui/components/presenter/ImageSlide.svelte +1 -1
- package/dist/ui/components/presenter/ImageSlide.svelte.d.ts +2 -2
- package/dist/ui/components/presenter/Presenter.state.svelte.d.ts +3 -3
- package/dist/ui/components/presenter/Presenter.state.svelte.js +1 -1
- package/dist/ui/components/presenter/Presenter.svelte +1 -1
- package/dist/ui/components/presenter/Presenter.svelte.d.ts +1 -1
- package/dist/ui/{primitives → components}/rows/panel-grid-row/PanelGridRow.svelte.d.ts +1 -1
- package/dist/ui/{primitives → components}/rows/panel-row-2/PanelRow2.svelte.d.ts +1 -1
- package/dist/ui/{primitives → components}/tab-bar/HkTabBar.state.svelte.d.ts +3 -3
- package/dist/ui/{primitives → components}/tab-bar/HkTabBar.state.svelte.js +4 -2
- package/dist/ui/{primitives → components}/tab-bar/HkTabBar.svelte +2 -2
- package/dist/ui/{primitives → components}/tab-bar/HkTabBar.svelte.d.ts +2 -2
- package/dist/ui/components/tab-bar/HkTabBarSelector.state.svelte.d.ts +19 -0
- package/dist/ui/{primitives → components}/tab-bar/HkTabBarSelector.state.svelte.js +2 -2
- package/dist/ui/{primitives → components}/tab-bar/HkTabBarSelector.svelte +1 -1
- package/dist/ui/{primitives → components}/tab-bar/HkTabBarSelector.svelte.d.ts +2 -2
- package/dist/ui/{primitives → components}/tab-bar/typedef.d.ts +1 -1
- package/dist/ui/{primitives → components}/tab-bar/typedef.js +1 -1
- package/dist/ui/components/typedef.d.ts +5 -0
- package/dist/ui/components/typedef.js +5 -0
- package/dist/ui/components/virtual-viewport/index.d.ts +1 -0
- package/dist/ui/components/virtual-viewport/index.js +1 -0
- package/dist/ui/components.d.ts +11 -0
- package/dist/ui/components.js +11 -0
- package/dist/ui/{primitives/hkdev → dev}/blocks/TextBlock.svelte +1 -1
- package/dist/ui/{primitives/debug → dev}/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +8 -8
- package/dist/ui/dev.d.ts +3 -0
- package/dist/ui/dev.js +3 -0
- package/dist/ui/primitives/buttons/button/Button.svelte.d.ts +1 -1
- package/dist/ui/primitives/buttons/button-text/TextButton.svelte +1 -1
- package/dist/ui/primitives/typedef.d.ts +1 -0
- package/dist/ui/primitives/typedef.js +1 -0
- package/dist/ui/primitives.d.ts +5 -0
- package/dist/ui/primitives.js +5 -0
- package/dist/ui/typedef.d.ts +2 -0
- package/dist/ui/typedef.js +2 -0
- package/dist/util/array/index.js +1 -1
- package/dist/util/bases/base58.d.ts +3 -3
- package/dist/util/bases/base58.js +3 -3
- package/dist/util/compare/index.d.ts +4 -5
- package/dist/util/compare/index.js +3 -4
- package/dist/util/exceptions/index.js +1 -1
- package/dist/util/expect/arrays.d.ts +11 -11
- package/dist/util/expect/arrays.js +14 -6
- package/dist/util/expect/index.js +2 -2
- package/dist/util/expect/primitives.d.ts +6 -5
- package/dist/util/expect/primitives.js +15 -5
- package/dist/util/expect/url.d.ts +6 -5
- package/dist/util/expect/url.js +15 -5
- package/dist/util/function/index.d.ts +1 -14
- package/dist/util/index.d.ts +5 -0
- package/dist/util/index.js +13 -0
- package/dist/util/is/index.d.ts +3 -2
- package/dist/util/is/index.js +2 -1
- package/dist/util/iterate/index.d.ts +6 -8
- package/dist/util/iterate/index.js +5 -5
- package/dist/util/object/index.d.ts +1 -2
- package/dist/util/object/index.js +2 -3
- package/dist/util/ssr/index.d.ts +16 -0
- package/dist/util/ssr/index.js +44 -0
- package/dist/util/svelte/index.d.ts +1 -1
- package/dist/util/svelte/index.js +1 -1
- package/dist/util/time/index.d.ts +2 -2
- package/dist/util/time/index.js +1 -1
- package/dist/valibot/index.d.ts +1 -1
- package/dist/valibot/index.js +27 -1
- package/package.json +4 -4
- package/dist/assets/autospuiten/car-paint-picker/army-green.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/electric-blue.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/lemon-yellow.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/opaque-purple.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/rusty.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/sunset-orange.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker/tomato-red.jpg +0 -0
- package/dist/assets/autospuiten/car-paint-picker.d.ts +0 -17
- package/dist/assets/autospuiten/car-paint-picker.js +0 -41
- package/dist/assets/autospuiten/labels.d.ts +0 -7
- package/dist/assets/autospuiten/labels.js +0 -7
- package/dist/classes/data/index.d.ts +0 -2
- package/dist/classes/data/index.js +0 -2
- package/dist/classes/event-emitter/index.d.ts +0 -1
- package/dist/classes/event-emitter/index.js +0 -2
- package/dist/classes/index.d.ts +0 -4
- package/dist/classes/index.js +0 -4
- package/dist/classes/promise/index.d.ts +0 -1
- package/dist/classes/promise/index.js +0 -1
- package/dist/classes/stores/index.d.ts +0 -1
- package/dist/classes/stores/index.js +0 -1
- package/dist/classes/streams/index.d.ts +0 -3
- package/dist/classes/streams/index.js +0 -3
- package/dist/classes/svelte/index.d.ts +0 -1
- package/dist/classes/svelte/index.js +0 -1
- package/dist/design/config/design-config.js +0 -73
- package/dist/design/tailwind-theme-extend.d.ts +0 -23
- package/dist/design/tailwind-theme-extend.js +0 -158
- package/dist/errors/index.d.ts +0 -5
- package/dist/errors/index.js +0 -5
- package/dist/logging/internal/factories/universal.d.ts +0 -9
- package/dist/logging/internal/factories/universal.js +0 -22
- package/dist/services/service-base/index.d.ts +0 -3
- package/dist/services/service-base/index.js +0 -3
- package/dist/states/index.d.ts +0 -1
- package/dist/states/index.js +0 -1
- package/dist/stores/index.d.ts +0 -1
- package/dist/stores/index.js +0 -1
- package/dist/typedef/index.d.ts +0 -4
- package/dist/typedef/index.js +0 -4
- package/dist/ui/primitives/debug/index.d.ts +0 -1
- package/dist/ui/primitives/debug/index.js +0 -1
- package/dist/ui/primitives/index.d.ts +0 -0
- package/dist/ui/primitives/index.js +0 -2
- package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte__heightFrom__ +0 -372
- package/dist/ui/primitives/layout/index.d.ts +0 -1
- package/dist/ui/primitives/layout/index.js +0 -1
- package/dist/ui/primitives/tab-bar/HkTabBarSelector.state.svelte.d.ts +0 -19
- /package/dist/{errors → auth/errors}/jwt.d.ts +0 -0
- /package/dist/{errors → auth/errors}/jwt.js +0 -0
- /package/dist/{states → browser/navigation}/navigation.svelte.d.ts +0 -0
- /package/dist/{classes/data → generic/data/classes}/IterableTree.d.ts +0 -0
- /package/dist/{classes/data → generic/data/classes}/Selector.d.ts +0 -0
- /package/dist/{classes → generic}/data/typedef.d.ts +0 -0
- /package/dist/{classes → generic}/data/typedef.js +0 -0
- /package/dist/{errors → generic/errors}/generic.d.ts +0 -0
- /package/dist/{errors → generic/errors}/generic.js +0 -0
- /package/dist/{errors → generic/errors}/promise.d.ts +0 -0
- /package/dist/{errors → generic/errors}/promise.js +0 -0
- /package/dist/{classes/event-emitter → generic/events/classes}/EventEmitter.d.ts +0 -0
- /package/dist/{classes/event-emitter → generic/events/classes}/EventEmitter.js +0 -0
- /package/dist/{classes/streams → generic/streaming/classes}/LogTransformStream.d.ts +0 -0
- /package/dist/{classes/streams → generic/streaming/classes}/LogTransformStream.js +0 -0
- /package/dist/{classes/streams → generic/streaming/classes}/TimeStampSource.d.ts +0 -0
- /package/dist/{classes/streams → generic/streaming/classes}/TimeStampSource.js +0 -0
- /package/dist/logging/{internal/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/logging/{internal/constants.js → constants.js} +0 -0
- /package/dist/logging/{internal/typedef.d.ts → typedef.d.ts} +0 -0
- /package/dist/logging/{internal/typedef.js → typedef.js} +0 -0
- /package/dist/{errors → network/errors}/api.d.ts +0 -0
- /package/dist/{errors → network/errors}/api.js +0 -0
- /package/dist/{errors → network/errors}/http.d.ts +0 -0
- /package/dist/{errors → network/errors}/http.js +0 -0
- /package/dist/{classes/svelte → state/classes}/finite-state-machine/FiniteStateMachine.svelte.d.ts +0 -0
- /package/dist/{classes/svelte → state/classes}/finite-state-machine/FiniteStateMachine.svelte.js +0 -0
- /package/dist/{classes/svelte → state/classes}/finite-state-machine/index.d.ts +0 -0
- /package/dist/{classes/svelte → state/classes}/finite-state-machine/index.js +0 -0
- /package/dist/{classes/svelte → state/classes}/loading-state-machine/constants.d.ts +0 -0
- /package/dist/{classes/svelte → state/classes}/loading-state-machine/constants.js +0 -0
- /package/dist/{classes/svelte → state/classes}/loading-state-machine/index.d.ts +0 -0
- /package/dist/{classes/svelte → state/classes}/loading-state-machine/index.js +0 -0
- /package/dist/{classes/stores → state/classes/subscribers-count}/SubscribersCount.d.ts +0 -0
- /package/dist/{classes/stores → state/classes/subscribers-count}/SubscribersCount.js +0 -0
- /package/dist/{typedef/context.d.ts → state/context/typedef.d.ts} +0 -0
- /package/dist/{typedef/context.js → state/context/typedef.js} +0 -0
- /package/dist/{stores → state/stores}/theme.d.ts +0 -0
- /package/dist/{stores → state/stores}/theme.js +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/DragController.d.ts +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/DragController.js +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/actions.d.ts +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/actions.js +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/index.d.ts +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/index.js +0 -0
- /package/dist/{typedef → ui/components/drag-drop/typedef}/drag.d.ts +0 -0
- /package/dist/{typedef → ui/components/drag-drop/typedef}/drag.js +0 -0
- /package/dist/{typedef → ui/components/drag-drop/typedef}/drop.d.ts +0 -0
- /package/dist/{typedef → ui/components/drag-drop/typedef}/drop.js +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/util.d.ts +0 -0
- /package/dist/ui/{primitives → components}/drag-drop/util.js +0 -0
- /package/dist/ui/{primitives/layout → components}/grid-layers/GridLayers.svelte +0 -0
- /package/dist/ui/{primitives/layout → components}/grid-layers/GridLayers.svelte.d.ts +0 -0
- /package/dist/ui/{primitives/layout → components}/grid-layers/util.d.ts +0 -0
- /package/dist/ui/{primitives → components}/rows/index.d.ts +0 -0
- /package/dist/ui/{primitives → components}/rows/index.js +0 -0
- /package/dist/ui/{primitives → components}/rows/panel-grid-row/PanelGridRow.svelte +0 -0
- /package/dist/ui/{primitives → components}/rows/panel-row-2/PanelRow2.svelte +0 -0
- /package/dist/ui/{primitives → components}/tab-bar/index.d.ts +0 -0
- /package/dist/ui/{primitives → components}/tab-bar/index.js +0 -0
- /package/dist/ui/{primitives/hkdev → dev}/blocks/TextBlock.svelte.d.ts +0 -0
- /package/dist/ui/{primitives/hkdev → dev}/buttons/CheckButton.svelte +0 -0
- /package/dist/ui/{primitives/hkdev → dev}/buttons/CheckButton.svelte.d.ts +0 -0
- /package/dist/ui/{primitives/debug → dev}/debug-panel-design-scaling/DebugPanelDesignScaling.svelte.d.ts +0 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared error formatting logic for logging adapters
|
|
3
|
+
*
|
|
4
|
+
* This module contains reusable functions for analyzing and formatting
|
|
5
|
+
* errors with enhanced stack trace detection and error type identification.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Find the most relevant frame index for highlighting in stack traces
|
|
10
|
+
*
|
|
11
|
+
* @param {Error} error - The error object
|
|
12
|
+
* @param {string[]} cleanedStack - Array of cleaned stack trace frames
|
|
13
|
+
* @returns {number} Index of the most relevant frame to highlight
|
|
14
|
+
*/
|
|
15
|
+
export function findRelevantFrameIndex(error, cleanedStack) {
|
|
16
|
+
// Check if this is a LoggerError - look for Logger.error call
|
|
17
|
+
if (error.name === 'LoggerError') {
|
|
18
|
+
const loggerErrorIndex = cleanedStack.findIndex(frame =>
|
|
19
|
+
frame.includes('Logger.error') && frame.includes('logger/Logger.js')
|
|
20
|
+
);
|
|
21
|
+
if (loggerErrorIndex >= 0 && loggerErrorIndex + 1 < cleanedStack.length) {
|
|
22
|
+
return loggerErrorIndex + 1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (error.name === 'ValiError') {
|
|
27
|
+
// Look for expect_ function first, user code is right after (handle Node.js format)
|
|
28
|
+
const expectIndex = cleanedStack.findIndex(frame =>
|
|
29
|
+
frame.includes('expect_') || frame.includes('Module.expect_')
|
|
30
|
+
);
|
|
31
|
+
if (expectIndex >= 0 && expectIndex + 1 < cleanedStack.length) {
|
|
32
|
+
return expectIndex + 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// If no expect_ function, look for valibotParser, user code is right after
|
|
36
|
+
const valibotIndex = cleanedStack.findIndex(frame => frame.includes('valibotParser'));
|
|
37
|
+
if (valibotIndex >= 0 && valibotIndex + 1 < cleanedStack.length) {
|
|
38
|
+
return valibotIndex + 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (error.name === 'DetailedError') {
|
|
43
|
+
// Check if this DetailedError was created by Logger.error - look for Logger.error call first
|
|
44
|
+
// Handle both Firefox format (error@file) and Node.js format (at Logger.error (file))
|
|
45
|
+
const loggerErrorIndex = cleanedStack.findIndex(frame =>
|
|
46
|
+
(frame.includes('Logger.error') && frame.includes('logger/Logger.js')) ||
|
|
47
|
+
(frame.includes('error@') && frame.includes('logger/Logger.js'))
|
|
48
|
+
);
|
|
49
|
+
if (loggerErrorIndex >= 0 && loggerErrorIndex + 1 < cleanedStack.length) {
|
|
50
|
+
return loggerErrorIndex + 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Look for rethrow, user code is right after (handle both Firefox and Node.js format)
|
|
54
|
+
const rethrowIndex = cleanedStack.findIndex(frame =>
|
|
55
|
+
frame.includes('rethrow@') || frame.includes('at rethrow (')
|
|
56
|
+
);
|
|
57
|
+
if (rethrowIndex >= 0 && rethrowIndex + 1 < cleanedStack.length) {
|
|
58
|
+
return rethrowIndex + 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (error.name === 'PromiseError') {
|
|
63
|
+
// Look for HkPromise methods, user code is right after
|
|
64
|
+
const hkPromiseIndex = cleanedStack.findIndex(frame =>
|
|
65
|
+
frame.includes('reject@') ||
|
|
66
|
+
frame.includes('tryReject@') ||
|
|
67
|
+
frame.includes('setTimeout@') ||
|
|
68
|
+
frame.includes('cancel@') ||
|
|
69
|
+
frame.includes('tryCancel@')
|
|
70
|
+
);
|
|
71
|
+
if (hkPromiseIndex >= 0 && hkPromiseIndex + 1 < cleanedStack.length) {
|
|
72
|
+
return hkPromiseIndex + 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (error.name === 'HttpError') {
|
|
77
|
+
// Find the last frame containing http-request.js, then highlight the next one
|
|
78
|
+
let lastHttpIndex = -1;
|
|
79
|
+
for (let i = 0; i < cleanedStack.length; i++) {
|
|
80
|
+
if (cleanedStack[i].includes('network/http/http-request.js')) {
|
|
81
|
+
lastHttpIndex = i;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (lastHttpIndex >= 0 && lastHttpIndex + 1 < cleanedStack.length) {
|
|
85
|
+
return lastHttpIndex + 1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Default to first frame
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Detect error metadata for structured logging and display
|
|
95
|
+
*
|
|
96
|
+
* @param {Error} error - The error object
|
|
97
|
+
* @param {string[]} cleanedStack - Array of cleaned stack trace frames
|
|
98
|
+
* @returns {import('./typedef.js').ErrorSummaryMeta} Error metadata
|
|
99
|
+
*/
|
|
100
|
+
export function detectErrorMeta(error, cleanedStack) {
|
|
101
|
+
const userFunctionName = extractUserFunctionName(error, cleanedStack);
|
|
102
|
+
const relevantFrameIndex = findRelevantFrameIndex(error, cleanedStack);
|
|
103
|
+
|
|
104
|
+
// Check if it's a LoggerError
|
|
105
|
+
if (error.name === 'LoggerError') {
|
|
106
|
+
return {
|
|
107
|
+
category: 'logger',
|
|
108
|
+
method: 'logger.error',
|
|
109
|
+
origin: userFunctionName,
|
|
110
|
+
relevantFrameIndex
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Check if it's a rethrow error
|
|
115
|
+
if (error.name === 'DetailedError') {
|
|
116
|
+
// Check if this DetailedError was created by Logger.error
|
|
117
|
+
const cleanedStackArray = cleanedStack || [];
|
|
118
|
+
const loggerErrorIndex = cleanedStackArray.findIndex(frame =>
|
|
119
|
+
(frame.includes('Logger.error') && frame.includes('logger/Logger.js')) ||
|
|
120
|
+
(frame.includes('error@') && frame.includes('logger/Logger.js'))
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
if (loggerErrorIndex >= 0) {
|
|
124
|
+
return {
|
|
125
|
+
category: 'logger',
|
|
126
|
+
method: 'logger.error',
|
|
127
|
+
origin: userFunctionName,
|
|
128
|
+
relevantFrameIndex
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Otherwise it's a regular rethrow error
|
|
133
|
+
return {
|
|
134
|
+
category: 'rethrow',
|
|
135
|
+
method: 'rethrow',
|
|
136
|
+
origin: userFunctionName,
|
|
137
|
+
relevantFrameIndex
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check if it's a PromiseError (HkPromise)
|
|
142
|
+
if (error.name === 'PromiseError') {
|
|
143
|
+
const hkPromiseMethod = getHkPromiseMethod(cleanedStack);
|
|
144
|
+
return {
|
|
145
|
+
category: 'promise',
|
|
146
|
+
method: hkPromiseMethod ? `hkpromise.${hkPromiseMethod}` : 'hkpromise',
|
|
147
|
+
origin: userFunctionName,
|
|
148
|
+
relevantFrameIndex
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Check if it's an HttpError
|
|
153
|
+
if (error.name === 'HttpError') {
|
|
154
|
+
const httpMethod = getHttpMethod(cleanedStack);
|
|
155
|
+
return {
|
|
156
|
+
category: 'http',
|
|
157
|
+
method: httpMethod || 'http',
|
|
158
|
+
origin: userFunctionName,
|
|
159
|
+
relevantFrameIndex
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Check if it's a valibot validation error
|
|
164
|
+
if (error.name === 'ValiError' && cleanedStack.length > 0) {
|
|
165
|
+
// Look for our valibotParser wrapper function in the stack
|
|
166
|
+
const valibotFrame = cleanedStack.find(frame =>
|
|
167
|
+
frame.includes('valibotParser')
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// Also check if it's called via an expect_ function (handle Node.js format)
|
|
171
|
+
const expectFrame = cleanedStack.find(frame =>
|
|
172
|
+
frame.includes('expect_') || frame.includes('Module.expect_')
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
if (valibotFrame || expectFrame) {
|
|
176
|
+
return {
|
|
177
|
+
category: 'validation',
|
|
178
|
+
method: expectFrame ? 'expect' : 'validation',
|
|
179
|
+
origin: userFunctionName,
|
|
180
|
+
relevantFrameIndex
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Default case
|
|
186
|
+
return {
|
|
187
|
+
category: 'error',
|
|
188
|
+
method: 'error',
|
|
189
|
+
origin: userFunctionName,
|
|
190
|
+
relevantFrameIndex
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Format error metadata for console display
|
|
196
|
+
*
|
|
197
|
+
* @param {{category: string, method: string, origin?: string|null}} errorMeta - Error metadata
|
|
198
|
+
* @returns {string} Formatted display string (e.g., "httpGet in myFunction")
|
|
199
|
+
*/
|
|
200
|
+
export function formatErrorDisplay(errorMeta) {
|
|
201
|
+
if (errorMeta.origin) {
|
|
202
|
+
return `${errorMeta.method} in ${errorMeta.origin}`;
|
|
203
|
+
}
|
|
204
|
+
return errorMeta.method;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Get the specific HkPromise method that caused the error
|
|
209
|
+
*
|
|
210
|
+
* @param {string[]} cleanedStack - Array of cleaned stack trace frames
|
|
211
|
+
* @returns {string|null} HkPromise method name or null
|
|
212
|
+
*/
|
|
213
|
+
export function getHkPromiseMethod(cleanedStack) {
|
|
214
|
+
const hkPromiseFrame = cleanedStack.find(frame =>
|
|
215
|
+
frame.includes('reject@') ||
|
|
216
|
+
frame.includes('tryReject@') ||
|
|
217
|
+
frame.includes('setTimeout@') ||
|
|
218
|
+
frame.includes('cancel@') ||
|
|
219
|
+
frame.includes('tryCancel@')
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
if (!hkPromiseFrame) return null;
|
|
223
|
+
|
|
224
|
+
if (hkPromiseFrame.includes('reject@')) return 'reject';
|
|
225
|
+
if (hkPromiseFrame.includes('tryReject@')) return 'tryReject';
|
|
226
|
+
if (hkPromiseFrame.includes('setTimeout@')) return 'setTimeout';
|
|
227
|
+
if (hkPromiseFrame.includes('cancel@')) return 'cancel';
|
|
228
|
+
if (hkPromiseFrame.includes('tryCancel@')) return 'tryCancel';
|
|
229
|
+
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get the specific HTTP method that caused the error
|
|
235
|
+
*
|
|
236
|
+
* @param {string[]} cleanedStack - Array of cleaned stack trace frames
|
|
237
|
+
* @returns {string|null} HTTP method name or null
|
|
238
|
+
*/
|
|
239
|
+
export function getHttpMethod(cleanedStack) {
|
|
240
|
+
const httpFrame = cleanedStack.find(frame =>
|
|
241
|
+
frame.includes('network/http/http-request.js')
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
if (!httpFrame) return null;
|
|
245
|
+
|
|
246
|
+
if (httpFrame.includes('httpGet@')) return 'httpGet';
|
|
247
|
+
if (httpFrame.includes('httpPost@')) return 'httpPost';
|
|
248
|
+
if (httpFrame.includes('httpPut@')) return 'httpPut';
|
|
249
|
+
if (httpFrame.includes('httpDelete@')) return 'httpDelete';
|
|
250
|
+
if (httpFrame.includes('httpPatch@')) return 'httpPatch';
|
|
251
|
+
if (httpFrame.includes('httpOptions@')) return 'httpOptions';
|
|
252
|
+
if (httpFrame.includes('httpRequest@')) return 'httpRequest';
|
|
253
|
+
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Extract user function name from stack trace
|
|
259
|
+
*
|
|
260
|
+
* @param {Error} error - The error object
|
|
261
|
+
* @param {string[]} cleanedStack - Array of cleaned stack trace frames
|
|
262
|
+
* @returns {string|null} User function name or null
|
|
263
|
+
*/
|
|
264
|
+
export function extractUserFunctionName(error, cleanedStack) {
|
|
265
|
+
// Check if this is a LoggerError - look for the frame after Logger.error
|
|
266
|
+
if (error.name === 'LoggerError' && cleanedStack.length > 1) {
|
|
267
|
+
const loggerErrorIndex = cleanedStack.findIndex(frame =>
|
|
268
|
+
frame.includes('Logger.error') && frame.includes('logger/Logger.js')
|
|
269
|
+
);
|
|
270
|
+
if (loggerErrorIndex >= 0 && loggerErrorIndex + 1 < cleanedStack.length) {
|
|
271
|
+
return parseFunctionName(cleanedStack[loggerErrorIndex + 1]);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (error.name === 'DetailedError' && cleanedStack.length > 1) {
|
|
276
|
+
// Check if this DetailedError was created by Logger.error - look for the frame after Logger.error
|
|
277
|
+
const loggerErrorIndex = cleanedStack.findIndex(frame =>
|
|
278
|
+
(frame.includes('Logger.error') && frame.includes('logger/Logger.js')) ||
|
|
279
|
+
(frame.includes('error@') && frame.includes('logger/Logger.js'))
|
|
280
|
+
);
|
|
281
|
+
if (loggerErrorIndex >= 0 && loggerErrorIndex + 1 < cleanedStack.length) {
|
|
282
|
+
return parseFunctionName(cleanedStack[loggerErrorIndex + 1]);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// For rethrow errors, look for the frame after rethrow (handle both formats)
|
|
286
|
+
const rethrowIndex = cleanedStack.findIndex(frame =>
|
|
287
|
+
frame.includes('rethrow@') || frame.includes('at rethrow (')
|
|
288
|
+
);
|
|
289
|
+
if (rethrowIndex >= 0 && rethrowIndex + 1 < cleanedStack.length) {
|
|
290
|
+
return parseFunctionName(cleanedStack[rethrowIndex + 1]);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (error.name === 'PromiseError' && cleanedStack.length > 1) {
|
|
295
|
+
// For PromiseError, look for the frame after HkPromise methods
|
|
296
|
+
const hkPromiseIndex = cleanedStack.findIndex(frame =>
|
|
297
|
+
frame.includes('reject@') ||
|
|
298
|
+
frame.includes('tryReject@') ||
|
|
299
|
+
frame.includes('setTimeout@') ||
|
|
300
|
+
frame.includes('cancel@') ||
|
|
301
|
+
frame.includes('tryCancel@')
|
|
302
|
+
);
|
|
303
|
+
if (hkPromiseIndex >= 0 && hkPromiseIndex + 1 < cleanedStack.length) {
|
|
304
|
+
return parseFunctionName(cleanedStack[hkPromiseIndex + 1]);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (error.name === 'HttpError' && cleanedStack.length > 1) {
|
|
309
|
+
// For HttpError, find the last frame containing http-request.js, then take the next one
|
|
310
|
+
let lastHttpIndex = -1;
|
|
311
|
+
for (let i = 0; i < cleanedStack.length; i++) {
|
|
312
|
+
if (cleanedStack[i].includes('network/http/http-request.js')) {
|
|
313
|
+
lastHttpIndex = i;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (lastHttpIndex >= 0 && lastHttpIndex + 1 < cleanedStack.length) {
|
|
317
|
+
return parseFunctionName(cleanedStack[lastHttpIndex + 1]);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (error.name === 'ValiError' && cleanedStack.length > 1) {
|
|
322
|
+
// For validation errors, look for the frame after expect_ function first (handle Node.js format)
|
|
323
|
+
const expectIndex = cleanedStack.findIndex(frame =>
|
|
324
|
+
frame.includes('expect_') || frame.includes('Module.expect_')
|
|
325
|
+
);
|
|
326
|
+
if (expectIndex >= 0 && expectIndex + 1 < cleanedStack.length) {
|
|
327
|
+
return parseFunctionName(cleanedStack[expectIndex + 1]);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// If no expect_ function, look for valibotParser wrapper
|
|
331
|
+
const valibotIndex = cleanedStack.findIndex(frame => frame.includes('valibotParser'));
|
|
332
|
+
if (valibotIndex >= 0 && valibotIndex + 1 < cleanedStack.length) {
|
|
333
|
+
return parseFunctionName(cleanedStack[valibotIndex + 1]);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Find the first meaningful function name (skip anonymous functions and framework code)
|
|
338
|
+
for (let i = 0; i < cleanedStack.length; i++) {
|
|
339
|
+
const functionName = parseFunctionName(cleanedStack[i]);
|
|
340
|
+
if (functionName && isMeaningfulFunctionName(functionName)) {
|
|
341
|
+
return functionName;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Check if function name is meaningful (not anonymous or framework code)
|
|
350
|
+
*
|
|
351
|
+
* @param {string} functionName - Function name to check
|
|
352
|
+
* @returns {boolean} True if the function name is meaningful
|
|
353
|
+
*/
|
|
354
|
+
export function isMeaningfulFunctionName(functionName) {
|
|
355
|
+
// Skip empty names, anonymous functions, and framework/internal functions
|
|
356
|
+
if (!functionName ||
|
|
357
|
+
functionName === '' ||
|
|
358
|
+
functionName.includes('<') ||
|
|
359
|
+
functionName.includes('/') ||
|
|
360
|
+
functionName.startsWith('async ') ||
|
|
361
|
+
functionName === 'async' ||
|
|
362
|
+
functionName === 'Promise' ||
|
|
363
|
+
functionName === 'new Promise' ||
|
|
364
|
+
functionName.includes('internal') ||
|
|
365
|
+
functionName.includes('node_modules')) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Parse function name from stack frame
|
|
374
|
+
*
|
|
375
|
+
* @param {string} frame - Stack trace frame
|
|
376
|
+
* @returns {string|null} Function name or null
|
|
377
|
+
*/
|
|
378
|
+
export function parseFunctionName(frame) {
|
|
379
|
+
// Handle both Firefox format: "functionName@file:line:col"
|
|
380
|
+
// and Node.js format: "at functionName (file:line:col)" or "at Module.functionName (file:line:col)"
|
|
381
|
+
|
|
382
|
+
// Firefox format
|
|
383
|
+
const firefoxMatch = frame.match(/^([^@]+)@/);
|
|
384
|
+
if (firefoxMatch) {
|
|
385
|
+
return firefoxMatch[1];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Node.js format
|
|
389
|
+
const nodeMatch = frame.match(/^\s*at\s+(?:Module\.)?([^\s(]+)/);
|
|
390
|
+
if (nodeMatch) {
|
|
391
|
+
return nodeMatch[1];
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pino adapter for server-side logging
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
import pino from 'pino';
|
|
6
5
|
import { dev } from '$app/environment';
|
|
7
6
|
|
|
7
|
+
import {
|
|
8
|
+
detectErrorMeta,
|
|
9
|
+
findRelevantFrameIndex,
|
|
10
|
+
formatErrorDisplay,
|
|
11
|
+
parseFunctionName
|
|
12
|
+
} from './formatting.js';
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* Pino adapter that bridges Logger events to pino
|
|
10
16
|
*/
|
|
@@ -21,28 +27,94 @@ export class PinoAdapter {
|
|
|
21
27
|
this.#projectRoot = import.meta.env.VITE_PROJECT_ROOT || process.cwd();
|
|
22
28
|
const baseOptions = {
|
|
23
29
|
serializers: {
|
|
24
|
-
|
|
30
|
+
errors: (err) => {
|
|
31
|
+
|
|
32
|
+
/** @type {import('./typedef').ErrorSummary[]} */
|
|
25
33
|
const chain = [];
|
|
34
|
+
let loggedAt = null;
|
|
35
|
+
|
|
26
36
|
let current = err;
|
|
27
37
|
let isFirst = true;
|
|
28
38
|
|
|
29
|
-
while (current) {
|
|
39
|
+
while (current && current instanceof Error) {
|
|
40
|
+
// Check if this is the first error and it's a LoggerError - extract logging context
|
|
41
|
+
if (isFirst && current.name === 'LoggerError') {
|
|
42
|
+
if (current.stack) {
|
|
43
|
+
const cleanedStackString = this.#cleanStackTrace(current.stack);
|
|
44
|
+
const cleanedStackArray = cleanedStackString
|
|
45
|
+
.split('\n')
|
|
46
|
+
.map((line) => line.trim())
|
|
47
|
+
.filter(
|
|
48
|
+
(line) =>
|
|
49
|
+
line && line !== current.name + ': ' + current.message
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// For LoggerError, we know it's a logger.error call, so find the relevant frame
|
|
53
|
+
const loggerErrorIndex = cleanedStackArray.findIndex(frame =>
|
|
54
|
+
(frame.includes('Logger.error') && frame.includes('logger/Logger.js')) ||
|
|
55
|
+
(frame.includes('error@') && frame.includes('logger/Logger.js'))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
if (loggerErrorIndex >= 0 && loggerErrorIndex + 1 < cleanedStackArray.length) {
|
|
59
|
+
const relevantFrame = cleanedStackArray[loggerErrorIndex + 1];
|
|
60
|
+
|
|
61
|
+
// Extract function name from the relevant frame
|
|
62
|
+
// const functionName = parseFunctionName(relevantFrame);
|
|
63
|
+
|
|
64
|
+
// const errorType = functionName ? `logger.error in ${functionName}` : 'logger.error';
|
|
65
|
+
loggedAt = relevantFrame.slice(3); // remove "at "
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Skip the LoggerError and move to the actual error
|
|
70
|
+
current = current.cause;
|
|
71
|
+
isFirst = false;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
30
74
|
/** @type {import('./typedef').ErrorSummary} */
|
|
31
75
|
const serialized = {
|
|
32
76
|
name: current.name,
|
|
33
|
-
message: current.message
|
|
34
|
-
...(isFirst &&
|
|
35
|
-
this.pino.level === 'debug' && {
|
|
36
|
-
stack: this.#cleanStackTrace(current.stack)
|
|
37
|
-
})
|
|
77
|
+
message: current.message
|
|
38
78
|
};
|
|
39
79
|
|
|
80
|
+
// Add error metadata for structured logging and terminal display
|
|
81
|
+
if (current.stack) {
|
|
82
|
+
// Convert cleaned stack string to array format expected by formatting functions
|
|
83
|
+
const cleanedStackString = this.#cleanStackTrace(current.stack);
|
|
84
|
+
const cleanedStackArray = cleanedStackString
|
|
85
|
+
.split('\n')
|
|
86
|
+
.map((line) => line.trim())
|
|
87
|
+
.filter(
|
|
88
|
+
(line) =>
|
|
89
|
+
line && line !== current.name + ': ' + current.message
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const errorMeta = detectErrorMeta(current, cleanedStackArray);
|
|
93
|
+
const relevantFrameIndex = findRelevantFrameIndex(
|
|
94
|
+
current,
|
|
95
|
+
cleanedStackArray
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
serialized.meta = errorMeta;
|
|
99
|
+
serialized.errorType = formatErrorDisplay(errorMeta);
|
|
100
|
+
|
|
101
|
+
// Include stack frames for terminal display
|
|
102
|
+
serialized.stackFrames = cleanedStackArray
|
|
103
|
+
.slice(0, 9)
|
|
104
|
+
.map((frame, index) => {
|
|
105
|
+
const marker = index === relevantFrameIndex ? '→' : ' ';
|
|
106
|
+
|
|
107
|
+
return `${marker} ${frame}`;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
40
111
|
// Include HttpError-specific properties
|
|
41
|
-
|
|
42
|
-
|
|
112
|
+
const httpError = /** @type {import('../../../network/errors.js').HttpError} */ (current);
|
|
113
|
+
if (httpError.status !== undefined) {
|
|
114
|
+
serialized.status = httpError.status;
|
|
43
115
|
}
|
|
44
|
-
if (
|
|
45
|
-
serialized.details =
|
|
116
|
+
if (httpError.details !== undefined) {
|
|
117
|
+
serialized.details = httpError.details;
|
|
46
118
|
}
|
|
47
119
|
|
|
48
120
|
chain.push(serialized);
|
|
@@ -50,19 +122,20 @@ export class PinoAdapter {
|
|
|
50
122
|
isFirst = false;
|
|
51
123
|
}
|
|
52
124
|
|
|
53
|
-
return {
|
|
125
|
+
return loggedAt ? { chain, loggedAt } : chain;
|
|
54
126
|
}
|
|
55
127
|
}
|
|
56
128
|
};
|
|
57
129
|
|
|
58
130
|
// Add error handling for missing pino-pretty in dev
|
|
59
|
-
if (dev) {
|
|
131
|
+
if ( dev) {
|
|
60
132
|
const devOptions = {
|
|
61
133
|
level: 'debug',
|
|
62
134
|
transport: {
|
|
63
135
|
target: 'pino-pretty',
|
|
64
136
|
options: {
|
|
65
|
-
colorize: true
|
|
137
|
+
colorize: true,
|
|
138
|
+
ignore: 'hostname,pid'
|
|
66
139
|
}
|
|
67
140
|
}
|
|
68
141
|
};
|
|
@@ -70,7 +143,10 @@ export class PinoAdapter {
|
|
|
70
143
|
try {
|
|
71
144
|
this.pino = pino({ ...baseOptions, ...devOptions, ...options });
|
|
72
145
|
} catch (error) {
|
|
73
|
-
if (
|
|
146
|
+
if (
|
|
147
|
+
error.message.includes('Cannot find module') &&
|
|
148
|
+
error.message.includes('pino-pretty')
|
|
149
|
+
) {
|
|
74
150
|
const errorMessage = `
|
|
75
151
|
╭─────────────────────────────────────────────────────────────╮
|
|
76
152
|
│ Missing Dependency │
|
|
@@ -89,7 +165,7 @@ export class PinoAdapter {
|
|
|
89
165
|
}
|
|
90
166
|
|
|
91
167
|
/**
|
|
92
|
-
* Clean stack trace by removing project root path
|
|
168
|
+
* Clean stack trace by removing project root path and simplifying node_modules
|
|
93
169
|
*
|
|
94
170
|
* @param {string} stack - Original stack trace
|
|
95
171
|
* @returns {string} Cleaned stack trace
|
|
@@ -99,15 +175,33 @@ export class PinoAdapter {
|
|
|
99
175
|
return stack;
|
|
100
176
|
}
|
|
101
177
|
|
|
178
|
+
let cleaned = stack;
|
|
179
|
+
|
|
102
180
|
// Escape special regex characters in the project root path
|
|
103
|
-
const escapedRoot = this.#projectRoot.replace(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
181
|
+
const escapedRoot = this.#projectRoot.replace(
|
|
182
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
183
|
+
'\\$&'
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
// Replace project root path with relative path, handling file:// protocol
|
|
187
|
+
// Match both regular paths and file:// URLs
|
|
188
|
+
const rootRegex = new RegExp(
|
|
189
|
+
`(\\s+at\\s+.*\\()(file://)?${escapedRoot}[\\/\\\\]`,
|
|
190
|
+
'g'
|
|
191
|
+
);
|
|
192
|
+
cleaned = cleaned.replace(rootRegex, '$1');
|
|
193
|
+
|
|
194
|
+
// Simplify pnpm paths: node_modules/.pnpm/package@version_deps/node_modules/package
|
|
195
|
+
// becomes: node_modules/package
|
|
196
|
+
const pnpmRegex =
|
|
197
|
+
/node_modules\/\.pnpm\/([^@\/]+)@[^\/]+\/node_modules\/\1/g;
|
|
198
|
+
cleaned = cleaned.replace(pnpmRegex, 'node_modules/$1');
|
|
199
|
+
|
|
200
|
+
// Also handle cases where the package name might be different in the final path
|
|
201
|
+
const pnpmRegex2 = /node_modules\/\.pnpm\/[^\/]+\/node_modules\/([^\/]+)/g;
|
|
202
|
+
cleaned = cleaned.replace(pnpmRegex2, 'node_modules/$1');
|
|
203
|
+
|
|
204
|
+
return cleaned;
|
|
111
205
|
}
|
|
112
206
|
|
|
113
207
|
/**
|
|
@@ -127,11 +221,12 @@ export class PinoAdapter {
|
|
|
127
221
|
if (details) {
|
|
128
222
|
if (details instanceof Error) {
|
|
129
223
|
// details is directly an error
|
|
130
|
-
logData.
|
|
224
|
+
logData.errors = details;
|
|
131
225
|
} else if (details.error instanceof Error) {
|
|
132
226
|
// details has an error property
|
|
133
|
-
logData.
|
|
227
|
+
logData.errors = details.error;
|
|
134
228
|
// Include other details except the error
|
|
229
|
+
// eslint-disable-next-line no-unused-vars
|
|
135
230
|
const { error, ...otherDetails } = details;
|
|
136
231
|
if (Object.keys(otherDetails).length > 0) {
|
|
137
232
|
logData.details = otherDetails;
|
|
@@ -142,6 +237,12 @@ export class PinoAdapter {
|
|
|
142
237
|
}
|
|
143
238
|
}
|
|
144
239
|
|
|
240
|
+
// Check if we have loggedAt info from the serializer
|
|
241
|
+
if (logData.errors && typeof logData.errors === 'object' && logData.errors.loggedAt) {
|
|
242
|
+
logData.loggedAt = logData.errors.loggedAt;
|
|
243
|
+
logData.errors = logData.errors.chain;
|
|
244
|
+
}
|
|
245
|
+
|
|
145
246
|
this.pino[level](logData, message);
|
|
146
247
|
}
|
|
147
248
|
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
declare const _default: {};
|
|
2
2
|
export default _default;
|
|
3
|
+
export type ErrorSummaryMeta = {
|
|
4
|
+
/**
|
|
5
|
+
* - Error category (rethrow, validation, http, promise, error)
|
|
6
|
+
*/
|
|
7
|
+
category: string;
|
|
8
|
+
/**
|
|
9
|
+
* - Specific method (rethrow, expect, httpGet, hkpromise.timeout, etc)
|
|
10
|
+
*/
|
|
11
|
+
method: string;
|
|
12
|
+
/**
|
|
13
|
+
* - User function name where error originated
|
|
14
|
+
*/
|
|
15
|
+
origin?: string;
|
|
16
|
+
/**
|
|
17
|
+
* - Index of most relevant stack frame to highlight
|
|
18
|
+
*/
|
|
19
|
+
relevantFrameIndex?: number;
|
|
20
|
+
};
|
|
3
21
|
export type ErrorSummary = {
|
|
4
22
|
/**
|
|
5
23
|
* - The name of the exception/error
|
|
@@ -9,6 +27,10 @@ export type ErrorSummary = {
|
|
|
9
27
|
* - The error message
|
|
10
28
|
*/
|
|
11
29
|
message: string;
|
|
30
|
+
/**
|
|
31
|
+
* - Error meta
|
|
32
|
+
*/
|
|
33
|
+
meta?: ErrorSummaryMeta;
|
|
12
34
|
/**
|
|
13
35
|
* Stack trace (in debug mode for first exception)
|
|
14
36
|
*/
|
|
@@ -21,4 +43,12 @@ export type ErrorSummary = {
|
|
|
21
43
|
* - Additional error details (for HttpError instances)
|
|
22
44
|
*/
|
|
23
45
|
details?: any;
|
|
46
|
+
/**
|
|
47
|
+
* - Formatted error type for display
|
|
48
|
+
*/
|
|
49
|
+
errorType?: string;
|
|
50
|
+
/**
|
|
51
|
+
* - Cleaned stack frames for terminal display
|
|
52
|
+
*/
|
|
53
|
+
stackFrames?: string[];
|
|
24
54
|
};
|