1 |
|
2 | const errorRecords = new WeakMap();
|
3 | const { error: logError } = console;
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | export default function errorRecord(error, window, context, customStack) {
|
16 | const { Date, Math } = window;
|
17 | let record = errorRecords.get(error);
|
18 | if (record) {
|
19 | return record;
|
20 | }
|
21 | record = { error, loc: '' };
|
22 | const { constructor, message, name } = error;
|
23 | // Reasonably unique, yet readable error ID.
|
24 | const seconds = new Date().getSeconds();
|
25 | const randomChar = Math.random()
|
26 | .toString(36)
|
27 | .slice(2, 3)
|
28 | .toUpperCase();
|
29 | record.id =
|
30 | ((constructor && constructor.name) || name) + seconds + randomChar;
|
31 |
|
32 | // Add offending line, if possible.
|
33 | let stack;
|
34 | if (customStack) {
|
35 | stack = customStack;
|
36 | } else {
|
37 |
|
38 | if (Error.captureStackTrace) {
|
39 | Error.captureStackTrace(error, context);
|
40 | }
|
41 | stack = error.stack;
|
42 | }
|
43 | const messageStart = stack.indexOf(message);
|
44 | if (messageStart > -1) {
|
45 | const traceStart = messageStart + message.length;
|
46 | record.loc = stack
|
47 | .slice(traceStart)
|
48 | .replace(window.location.origin, '')
|
49 | .trim()
|
50 | .split('\n')[0];
|
51 | }
|
52 | errorRecords.set(error, record);
|
53 |
|
54 |
|
55 |
|
56 | if (process.env.NODE_ENV === 'production') {
|
57 | logError(
|
58 | `%cUnhandled ${record.id}`,
|
59 | 'background: #CC0000; color: white; padding: 0.1em 0.5em',
|
60 | stack
|
61 | );
|
62 | }
|
63 | return record;
|
64 | }
|