-
Notifications
You must be signed in to change notification settings - Fork 382
/
errors.ts
182 lines (161 loc) · 5.97 KB
/
errors.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
* Copyright (c) 2024, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import { templateString } from '../shared/utils';
import { LWCErrorInfo } from '../shared/types';
import {
CompilerDiagnosticOrigin,
CompilerDiagnostic,
CompilerError,
getCodeFromError,
getFilename,
getLocation,
} from './utils';
export { CompilerDiagnosticOrigin, CompilerDiagnostic, CompilerError } from './utils';
export * from './error-info';
// TODO [#1289]: Can be flattened now that we're down to only 2 properties
export interface ErrorConfig {
messageArgs?: any[];
origin?: CompilerDiagnosticOrigin;
}
/**
* Generates a friendly error message for the given error type, using the provided template values.
* @param errorInfo The object holding the error metadata.
* @param args Values used to fill the error message template.
* @returns The generated error message.
*/
export function generateErrorMessage(errorInfo: LWCErrorInfo, args?: any[]): string {
const message = Array.isArray(args)
? templateString(errorInfo.message, args)
: errorInfo.message;
if (errorInfo.url && errorInfo.url !== '') {
// TODO [#1289]: Add url info into message
}
return `LWC${errorInfo.code}: ${message}`;
}
/**
* Generates a compiler diagnostic. This function is used to look up the specified errorInfo
* and generate a friendly and consistent diagnostic object. Diagnostic contains
* info about the error's code and its origin (filename, line, column) when applicable.
* @param errorInfo The object holding the error metadata.
* @param config A config object providing any message arguments and origin info needed to create the error.
* @returns The generated compiler diagnostic object.
*/
export function generateCompilerDiagnostic(
errorInfo: LWCErrorInfo,
config?: ErrorConfig
): CompilerDiagnostic {
const message = generateErrorMessage(errorInfo, config && config.messageArgs);
const diagnostic: CompilerDiagnostic = {
code: errorInfo.code,
message,
level: errorInfo.level,
};
if (config && config.origin) {
diagnostic.filename = getFilename(config.origin);
diagnostic.location = getLocation(config.origin);
}
return diagnostic;
}
/**
* Generates a compiler error. This function is used to look up the specified errorInfo
* and generate a friendly and consistent error object. Error object contains info about
* the error's code and its origin (filename, line, column) when applicable.
* @param errorInfo The object holding the error metadata.
* @param config A config object providing any message arguments and origin info needed to create the error.
* @returns The generated compiler error.
*/
export function generateCompilerError(
errorInfo: LWCErrorInfo,
config?: ErrorConfig
): CompilerError {
const message = generateErrorMessage(errorInfo, config && config.messageArgs);
const error = new CompilerError(errorInfo.code, message);
if (config) {
error.filename = getFilename(config.origin);
error.location = getLocation(config.origin);
}
return error;
}
/**
* Validates that the provided condition is truthy.
* @param condition Condition to check.
* @param errorInfo The object holding the error metadata.
* @param args Values used to fill the error message template.
* @throws Throws a compiler error if the provided condition is falsy.
*/
export function invariant(condition: boolean, errorInfo: LWCErrorInfo, args?: any[]) {
if (!condition) {
throw generateCompilerError(errorInfo, {
messageArgs: args,
});
}
}
/**
* Normalizes a received error into a CompilerError. Adds any provided additional origin info.
* @param errorInfo The object holding the error metadata.
* @param error The original error.
* @param origin The origin associated with the error.
* @returns The normalized compiler error.
*/
export function normalizeToCompilerError(
errorInfo: LWCErrorInfo,
error: any,
origin?: CompilerDiagnosticOrigin
): CompilerError {
if (error instanceof CompilerError) {
if (origin) {
error.filename = getFilename(origin);
error.location = getLocation(origin);
}
return error;
}
const { code, message, filename, location } = convertErrorToDiagnostic(
error,
errorInfo,
origin
);
const compilerError = new CompilerError(code, `${error.name}: ${message}`, filename, location);
compilerError.stack = error.stack;
return compilerError;
}
/**
* Normalizes a received error into a CompilerDiagnostic. Adds any provided additional origin info.
* @param errorInfo The object holding the error metadata.
* @param error The original error.
* @param origin The origin of the error.
* @returns The normalized compiler diagnostic object.
*/
export function normalizeToDiagnostic(
errorInfo: LWCErrorInfo,
error: any,
origin?: CompilerDiagnosticOrigin
): CompilerDiagnostic {
if (error instanceof CompilerError) {
const diagnostic = error.toDiagnostic();
if (origin) {
diagnostic.filename = getFilename(origin);
diagnostic.location = getLocation(origin);
}
return diagnostic;
}
return convertErrorToDiagnostic(error, errorInfo, origin);
}
function convertErrorToDiagnostic(
error: any,
fallbackErrorInfo: LWCErrorInfo,
origin?: CompilerDiagnosticOrigin
): CompilerDiagnostic {
const code = getCodeFromError(error) || fallbackErrorInfo.code;
const message = error.lwcCode
? error.message
: generateErrorMessage(fallbackErrorInfo, [error.message]);
const level = error.level || fallbackErrorInfo.level;
const filename = getFilename(origin, error);
const location = getLocation(origin, error);
// TODO [#1289]: Preserve stack information
return { code, message, level, filename, location };
}