@office-iss/react-native-win32 0.72.9 → 0.72.10
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/CHANGELOG.json +16 -1
- package/CHANGELOG.md +12 -4
- package/Libraries/Core/ExceptionsManager.win32.js +252 -0
- package/overrides.json +6 -0
- package/package.json +1 -1
package/CHANGELOG.json
CHANGED
|
@@ -2,7 +2,22 @@
|
|
|
2
2
|
"name": "@office-iss/react-native-win32",
|
|
3
3
|
"entries": [
|
|
4
4
|
{
|
|
5
|
-
"date": "Mon,
|
|
5
|
+
"date": "Mon, 20 Nov 2023 21:39:10 GMT",
|
|
6
|
+
"tag": "@office-iss/react-native-win32_v0.72.10",
|
|
7
|
+
"version": "0.72.10",
|
|
8
|
+
"comments": {
|
|
9
|
+
"patch": [
|
|
10
|
+
{
|
|
11
|
+
"author": "30809111+acoates-ms@users.noreply.github.com",
|
|
12
|
+
"package": "@office-iss/react-native-win32",
|
|
13
|
+
"commit": "54238c066a0c59050486694e9da61728798cadc8",
|
|
14
|
+
"comment": "Call exceptions manager even in DEV bundles"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"date": "Mon, 30 Oct 2023 15:15:13 GMT",
|
|
6
21
|
"tag": "@office-iss/react-native-win32_v0.72.9",
|
|
7
22
|
"version": "0.72.9",
|
|
8
23
|
"comments": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
# Change Log - @office-iss/react-native-win32
|
|
2
2
|
|
|
3
|
-
This log was last generated on Mon,
|
|
3
|
+
This log was last generated on Mon, 20 Nov 2023 21:39:10 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
-
## 0.72.
|
|
7
|
+
## 0.72.10
|
|
8
8
|
|
|
9
|
-
Mon,
|
|
9
|
+
Mon, 20 Nov 2023 21:39:10 GMT
|
|
10
10
|
|
|
11
11
|
### Patches
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- Call exceptions manager even in DEV bundles (30809111+acoates-ms@users.noreply.github.com)
|
|
14
14
|
|
|
15
|
+
## 0.72.9
|
|
16
|
+
|
|
17
|
+
Mon, 30 Oct 2023 15:15:13 GMT
|
|
18
|
+
|
|
19
|
+
### Patches
|
|
20
|
+
|
|
21
|
+
- Fix peer dependencies for react-native (jthysell@microsoft.com)
|
|
22
|
+
|
|
15
23
|
## 0.72.8
|
|
16
24
|
|
|
17
25
|
Fri, 20 Oct 2023 23:18:35 GMT
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @flow strict
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
import type {ExtendedError} from './ExtendedError';
|
|
14
|
+
import type {ExceptionData} from './NativeExceptionsManager';
|
|
15
|
+
|
|
16
|
+
class SyntheticError extends Error {
|
|
17
|
+
name: string = '';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type ExceptionDecorator = ExceptionData => ExceptionData;
|
|
21
|
+
|
|
22
|
+
let userExceptionDecorator: ?ExceptionDecorator;
|
|
23
|
+
let inUserExceptionDecorator = false;
|
|
24
|
+
|
|
25
|
+
// This Symbol is used to decorate an ExtendedError with extra data in select usecases.
|
|
26
|
+
// Note that data passed using this method should be strictly contained,
|
|
27
|
+
// as data that's not serializable/too large may cause issues with passing the error to the native code.
|
|
28
|
+
const decoratedExtraDataKey: symbol = Symbol('decoratedExtraDataKey');
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Allows the app to add information to the exception report before it is sent
|
|
32
|
+
* to native. This API is not final.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
function unstable_setExceptionDecorator(
|
|
36
|
+
exceptionDecorator: ?ExceptionDecorator,
|
|
37
|
+
) {
|
|
38
|
+
userExceptionDecorator = exceptionDecorator;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function preprocessException(data: ExceptionData): ExceptionData {
|
|
42
|
+
if (userExceptionDecorator && !inUserExceptionDecorator) {
|
|
43
|
+
inUserExceptionDecorator = true;
|
|
44
|
+
try {
|
|
45
|
+
return userExceptionDecorator(data);
|
|
46
|
+
} catch {
|
|
47
|
+
// Fall through
|
|
48
|
+
} finally {
|
|
49
|
+
inUserExceptionDecorator = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Handles the developer-visible aspect of errors and exceptions
|
|
57
|
+
*/
|
|
58
|
+
let exceptionID = 0;
|
|
59
|
+
function reportException(
|
|
60
|
+
e: ExtendedError,
|
|
61
|
+
isFatal: boolean,
|
|
62
|
+
reportToConsole: boolean, // only true when coming from handleException; the error has not yet been logged
|
|
63
|
+
) {
|
|
64
|
+
const parseErrorStack = require('./Devtools/parseErrorStack');
|
|
65
|
+
const stack = parseErrorStack(e?.stack);
|
|
66
|
+
const currentExceptionID = ++exceptionID;
|
|
67
|
+
const originalMessage = e.message || '';
|
|
68
|
+
let message = originalMessage;
|
|
69
|
+
if (e.componentStack != null) {
|
|
70
|
+
message += `\n\nThis error is located at:${e.componentStack}`;
|
|
71
|
+
}
|
|
72
|
+
const namePrefix = e.name == null || e.name === '' ? '' : `${e.name}: `;
|
|
73
|
+
|
|
74
|
+
if (!message.startsWith(namePrefix)) {
|
|
75
|
+
message = namePrefix + message;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
message =
|
|
79
|
+
e.jsEngine == null ? message : `${message}, js engine: ${e.jsEngine}`;
|
|
80
|
+
|
|
81
|
+
const data = preprocessException({
|
|
82
|
+
message,
|
|
83
|
+
originalMessage: message === originalMessage ? null : originalMessage,
|
|
84
|
+
name: e.name == null || e.name === '' ? null : e.name,
|
|
85
|
+
componentStack:
|
|
86
|
+
typeof e.componentStack === 'string' ? e.componentStack : null,
|
|
87
|
+
stack,
|
|
88
|
+
id: currentExceptionID,
|
|
89
|
+
isFatal,
|
|
90
|
+
extraData: {
|
|
91
|
+
// $FlowFixMe[incompatible-use] we can't define a type with a Symbol-keyed field in flow
|
|
92
|
+
...e[decoratedExtraDataKey],
|
|
93
|
+
jsEngine: e.jsEngine,
|
|
94
|
+
rawStack: e.stack,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (reportToConsole) {
|
|
99
|
+
// we feed back into console.error, to make sure any methods that are
|
|
100
|
+
// monkey patched on top of console.error are called when coming from
|
|
101
|
+
// handleException
|
|
102
|
+
console.error(data.message);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (__DEV__) {
|
|
106
|
+
const LogBox = require('../LogBox/LogBox').default;
|
|
107
|
+
LogBox.addException({
|
|
108
|
+
...data,
|
|
109
|
+
isComponentError: !!e.isComponentError,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// [Win32] Always call into NativeExceptionsManager - even on debug
|
|
113
|
+
if (isFatal || e.type !== 'warn') {
|
|
114
|
+
const NativeExceptionsManager =
|
|
115
|
+
require('./NativeExceptionsManager').default;
|
|
116
|
+
if (NativeExceptionsManager) {
|
|
117
|
+
NativeExceptionsManager.reportException(data);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare var console: typeof console & {
|
|
123
|
+
_errorOriginal: typeof console.error,
|
|
124
|
+
reportErrorsAsExceptions: boolean,
|
|
125
|
+
...
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// If we trigger console.error _from_ handleException,
|
|
129
|
+
// we do want to make sure that console.error doesn't trigger error reporting again
|
|
130
|
+
let inExceptionHandler = false;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Logs exceptions to the (native) console and displays them
|
|
134
|
+
*/
|
|
135
|
+
function handleException(e: mixed, isFatal: boolean) {
|
|
136
|
+
let error: Error;
|
|
137
|
+
if (e instanceof Error) {
|
|
138
|
+
error = e;
|
|
139
|
+
} else {
|
|
140
|
+
// Workaround for reporting errors caused by `throw 'some string'`
|
|
141
|
+
// Unfortunately there is no way to figure out the stacktrace in this
|
|
142
|
+
// case, so if you ended up here trying to trace an error, look for
|
|
143
|
+
// `throw '<error message>'` somewhere in your codebase.
|
|
144
|
+
error = new SyntheticError(e);
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
inExceptionHandler = true;
|
|
148
|
+
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
|
|
149
|
+
* parameters */
|
|
150
|
+
reportException(error, isFatal, /*reportToConsole*/ true);
|
|
151
|
+
} finally {
|
|
152
|
+
inExceptionHandler = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
|
|
157
|
+
* LTI update could not be added via codemod */
|
|
158
|
+
function reactConsoleErrorHandler(...args) {
|
|
159
|
+
// bubble up to any original handlers
|
|
160
|
+
console._errorOriginal(...args);
|
|
161
|
+
if (!console.reportErrorsAsExceptions) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (inExceptionHandler) {
|
|
165
|
+
// The fundamental trick here is that are multiple entry point to logging errors:
|
|
166
|
+
// (see D19743075 for more background)
|
|
167
|
+
//
|
|
168
|
+
// 1. An uncaught exception being caught by the global handler
|
|
169
|
+
// 2. An error being logged throw console.error
|
|
170
|
+
//
|
|
171
|
+
// However, console.error is monkey patched multiple times: by this module, and by the
|
|
172
|
+
// DevTools setup that sends messages to Metro.
|
|
173
|
+
// The patching order cannot be relied upon.
|
|
174
|
+
//
|
|
175
|
+
// So, some scenarios that are handled by this flag:
|
|
176
|
+
//
|
|
177
|
+
// Logging an error:
|
|
178
|
+
// 1. console.error called from user code
|
|
179
|
+
// 2. (possibly) arrives _first_ at DevTool handler, send to Metro
|
|
180
|
+
// 3. Bubbles to here
|
|
181
|
+
// 4. goes into report Exception.
|
|
182
|
+
// 5. should not trigger console.error again, to avoid looping / logging twice
|
|
183
|
+
// 6. should still bubble up to original console
|
|
184
|
+
// (which might either be console.log, or the DevTools handler in case it patched _earlier_ and (2) didn't happen)
|
|
185
|
+
//
|
|
186
|
+
// Throwing an uncaught exception:
|
|
187
|
+
// 1. exception thrown
|
|
188
|
+
// 2. picked up by handleException
|
|
189
|
+
// 3. should be sent to console.error (not console._errorOriginal, as DevTools might have patched _later_ and it needs to send it to Metro)
|
|
190
|
+
// 4. that _might_ bubble again to the `reactConsoleErrorHandle` defined here
|
|
191
|
+
// -> should not handle exception _again_, to avoid looping / showing twice (this code branch)
|
|
192
|
+
// 5. should still bubble up to original console (which might either be console.log, or the DevTools handler in case that one patched _earlier_)
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
let error;
|
|
197
|
+
|
|
198
|
+
const firstArg = args[0];
|
|
199
|
+
if (firstArg?.stack) {
|
|
200
|
+
// reportException will console.error this with high enough fidelity.
|
|
201
|
+
error = firstArg;
|
|
202
|
+
} else {
|
|
203
|
+
const stringifySafe = require('../Utilities/stringifySafe').default;
|
|
204
|
+
if (typeof firstArg === 'string' && firstArg.startsWith('Warning: ')) {
|
|
205
|
+
// React warnings use console.error so that a stack trace is shown, but
|
|
206
|
+
// we don't (currently) want these to show a redbox
|
|
207
|
+
// (Note: Logic duplicated in polyfills/console.js.)
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const message = args
|
|
211
|
+
.map(arg => (typeof arg === 'string' ? arg : stringifySafe(arg)))
|
|
212
|
+
.join(' ');
|
|
213
|
+
|
|
214
|
+
error = new SyntheticError(message);
|
|
215
|
+
error.name = 'console.error';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
reportException(
|
|
219
|
+
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
|
|
220
|
+
* parameters */
|
|
221
|
+
error,
|
|
222
|
+
false, // isFatal
|
|
223
|
+
false, // reportToConsole
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Shows a redbox with stacktrace for all console.error messages. Disable by
|
|
229
|
+
* setting `console.reportErrorsAsExceptions = false;` in your app.
|
|
230
|
+
*/
|
|
231
|
+
function installConsoleErrorReporter() {
|
|
232
|
+
// Enable reportErrorsAsExceptions
|
|
233
|
+
if (console._errorOriginal) {
|
|
234
|
+
return; // already installed
|
|
235
|
+
}
|
|
236
|
+
// Flow doesn't like it when you set arbitrary values on a global object
|
|
237
|
+
console._errorOriginal = console.error.bind(console);
|
|
238
|
+
console.error = reactConsoleErrorHandler;
|
|
239
|
+
if (console.reportErrorsAsExceptions === undefined) {
|
|
240
|
+
// Individual apps can disable this
|
|
241
|
+
// Flow doesn't like it when you set arbitrary values on a global object
|
|
242
|
+
console.reportErrorsAsExceptions = true;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
module.exports = {
|
|
247
|
+
decoratedExtraDataKey,
|
|
248
|
+
handleException,
|
|
249
|
+
installConsoleErrorReporter,
|
|
250
|
+
SyntheticError,
|
|
251
|
+
unstable_setExceptionDecorator,
|
|
252
|
+
};
|
package/overrides.json
CHANGED
|
@@ -231,6 +231,12 @@
|
|
|
231
231
|
"type": "platform",
|
|
232
232
|
"file": "src/Libraries/Components/View/ViewWin32.js"
|
|
233
233
|
},
|
|
234
|
+
{
|
|
235
|
+
"type": "derived",
|
|
236
|
+
"file": "src/Libraries/Core/ExceptionsManager.win32.js",
|
|
237
|
+
"baseFile": "packages/react-native/Libraries/Core/ExceptionsManager.js",
|
|
238
|
+
"baseHash": "5a7a7f5bd7a70853c96422f05b59b5c2c5328ac5"
|
|
239
|
+
},
|
|
234
240
|
{
|
|
235
241
|
"type": "patch",
|
|
236
242
|
"file": "src/Libraries/Core/ReactNativeVersionCheck.win32.js",
|