• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pallad-ts / error-mapper / f74da6f4-8690-4cfe-9d68-3154b6ffa897

27 Nov 2025 09:26PM UTC coverage: 89.394%. Remained the same
f74da6f4-8690-4cfe-9d68-3154b6ffa897

push

circleci

wookieb
1.2.1

15 of 21 branches covered (71.43%)

Branch coverage included in aggregate %.

44 of 45 relevant lines covered (97.78%)

9.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.39
/src/ErrorMapperBuilder.ts
1
import {ErrorOutput} from "./ErrorOutput";
2
import {ErrorMapper} from "./ErrorMapper";
3
import {Builder} from "@pallad/builder";
1✔
4
import {AnyInfo, info} from "@pallad/app-env";
1✔
5
import {OutputTransformer} from "./OutputTransformer";
6
import {ErrorMapping} from "./ErrorMapping";
7
import {UnknownErrorListener} from "./UnknownErrorListener";
8

9
export class ErrorMapperBuilder<TOutput extends ErrorOutput> extends Builder {
1✔
10
        private mappings: Array<ErrorMapping<TOutput>> = [];
14✔
11
        private onUnknownErrorListeners: UnknownErrorListener[] = [];
14✔
12
        private outputTransformers: Array<OutputTransformer<TOutput>> = [];
14✔
13

14
        constructor(private options: ErrorMapperBuilder.Options = {
14!
15
                showStackTrace: false,
16
                showUnknownErrorMessage: false
17
        }) {
18
                super();
14✔
19
        }
20

21
        setOptions(options: Partial<ErrorMapperBuilder.Options>) {
22
                this.options = {
2✔
23
                        ...this.options,
24
                        ...options
25
                };
26
                return this;
2✔
27
        }
28

29
        /**
30
         * Creates preconfigured mapper with options suitable for environment
31

32
         */
33
        static fromEnv<TOutput extends ErrorOutput, TInfo extends AnyInfo = AnyInfo>(env: TInfo): ErrorMapperBuilder<TOutput>;
34
        static fromEnv(env: AnyInfo = info): ErrorMapperBuilder<ErrorOutput> {
×
35
                return new ErrorMapperBuilder<ErrorOutput>({
×
36
                        showStackTrace: env.isDevelopment || env.isTest,
×
37
                        showUnknownErrorMessage: env.isDevelopment || env.isTest
×
38
                });
39
        }
40

41
        registerOutputTransformer(transformer: OutputTransformer<TOutput>) {
42
                this.outputTransformers.push(transformer);
26✔
43
                return this;
26✔
44
        }
45

46
        onUnknownError(listener: UnknownErrorListener) {
47
                this.onUnknownErrorListeners.push(listener);
4✔
48
                return this;
4✔
49
        }
50

51
        registerMapping(mapper: ErrorMapping<TOutput>): this {
52
                this.mappings.push(mapper);
7✔
53
                return this;
7✔
54
        }
55

56
        get(): ErrorMapper<TOutput> {
57
                this.preconfigure();
14✔
58
                const computeInitialOutputForError = (err: unknown): TOutput | undefined => {
14✔
59
                        for (const mapping of this.mappings) {
16✔
60
                                const mappingResult = mapping(err);
7✔
61
                                if (mappingResult) {
7✔
62
                                        return mappingResult;
5✔
63
                                }
64
                        }
65
                }
66

67
                return (err: unknown): TOutput => {
14✔
68
                        const mappingResult = computeInitialOutputForError(err);
16✔
69
                        const errorMeta: OutputTransformer.Meta = {
16✔
70
                                isKnown: !!mappingResult
71
                        };
72

73
                        if (!mappingResult) {
16✔
74
                                for (const onUnknownErrorListener of this.onUnknownErrorListeners) {
11✔
75
                                        onUnknownErrorListener(err);
2✔
76
                                }
77
                        }
78

79
                        return this.outputTransformers.reduce(
16✔
80
                                (output, transformer) => {
81
                                        return transformer(output, err, errorMeta);
29✔
82
                                },
83
                                mappingResult ?? {
27✔
84
                                        message: err instanceof Error ? err.message : 'Unknown error'
11✔
85
                                } as TOutput
86
                        ) as TOutput;
87
                }
88
        }
89

90
        private preconfigure() {
91
                this.runIf(this.options.showStackTrace, () => {
14✔
92
                        this.registerOutputTransformer((output, error) => {
3✔
93
                                if (error && error instanceof Error && 'stack' in error) {
3✔
94
                                        return {
2✔
95
                                                ...output,
96
                                                stack: error.stack
97
                                        }
98
                                }
99

100
                                return output;
1✔
101
                        });
102
                });
103

104
                this.registerOutputTransformer((output, error) => {
14✔
105
                        if (error && typeof error === 'object' && 'code' in error) {
16✔
106
                                return {
1✔
107
                                        ...output,
108
                                        code: (error as { code: string }).code
109
                                };
110
                        }
111
                        return output;
15✔
112
                });
113

114
                this.runIf(!this.options.showUnknownErrorMessage, () => {
14✔
115
                        this.registerOutputTransformer((output, error, {isKnown}) => {
8✔
116
                                if (!isKnown) {
8✔
117
                                        return {
6✔
118
                                                ...output,
119
                                                message: 'Internal server error. Please try again later.'
120
                                        }
121
                                }
122
                                return output;
2✔
123
                        });
124
                })
125
        }
126
}
127

128
export namespace ErrorMapperBuilder {
129
        export interface Options {
130
                /**
131
                 * Whether to include stack trace in every error
132
                 */
133
                showStackTrace: boolean;
134

135
                /**
136
                 * Whether to show message of errors that have no registered mapper, for example for unknown or critical errors.
137
                 */
138
                showUnknownErrorMessage: boolean;
139
        }
140
}
141

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc