diff options
author | 2021-05-15 17:23:55 -0700 | |
---|---|---|
committer | 2021-05-15 17:23:55 -0700 | |
commit | e80f865974df7aae5e2f6abb966b36497da693c6 (patch) | |
tree | e82bcf4860c1fc43de189f13a18e8526a2966f44 /src/test/fixtures/react-dev-crash.js | |
parent | c88625436cf866bdaa68249d10880a2271f611e0 (diff) | |
download | bun-e80f865974df7aae5e2f6abb966b36497da693c6.tar.gz bun-e80f865974df7aae5e2f6abb966b36497da693c6.tar.zst bun-e80f865974df7aae5e2f6abb966b36497da693c6.zip |
lots
Former-commit-id: d8b1d296562a01800248bd1148bc4778225b436e
Diffstat (limited to 'src/test/fixtures/react-dev-crash.js')
-rw-r--r-- | src/test/fixtures/react-dev-crash.js | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/test/fixtures/react-dev-crash.js b/src/test/fixtures/react-dev-crash.js new file mode 100644 index 000000000..1bed979a5 --- /dev/null +++ b/src/test/fixtures/react-dev-crash.js @@ -0,0 +1,108 @@ +try { + // This should throw. + if (construct) { + // Something should be setting the props in the constructor. + var Fake = function () { + throw Error(); + }; // $FlowFixMe + + Object.defineProperty(Fake.prototype, "props", { + set: function () { + // We use a throwing setter instead of frozen or non-writable props + // because that won't throw in a non-strict mode function. + throw Error(); + }, + }); + + if (typeof Reflect === "object" && Reflect.construct) { + // We construct a different control for this case to include any extra + // frames added by the construct call. + try { + Reflect.construct(Fake, []); + } catch (x) { + control = x; + } + + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x) { + control = x; + } + + fn.call(Fake.prototype); + } + } else { + try { + throw Error(); + } catch (x) { + control = x; + } + + fn(); + } +} catch (sample) { + // This is inlined manually because closure doesn't do it for us. + if (sample && control && typeof sample.stack === "string") { + // This extracts the first frame from the sample that isn't also in the control. + // Skipping one frame that we assume is the frame that calls the two. + var sampleLines = sample.stack.split("\n"); + var controlLines = control.stack.split("\n"); + var s = sampleLines.length - 1; + var c = controlLines.length - 1; + + while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) { + // We expect at least one stack frame to be shared. + // Typically this will be the root most one. However, stack frames may be + // cut off due to maximum stack limits. In this case, one maybe cut off + // earlier than the other. We assume that the sample is longer or the same + // and there for cut off earlier. So we should find the root most frame in + // the sample somewhere in the control. + c--; + } + + for (; s >= 1 && c >= 0; s--, c--) { + // Next we find the first one that isn't the same which should be the + // frame that called our sample function and the control. + if (sampleLines[s] !== controlLines[c]) { + // In V8, the first line is describing the message but other VMs don't. + // If we're about to return the first line, and the control is also on the same + // line, that's a pretty good indicator that our sample threw at same line as + // the control. I.e. before we entered the sample frame. So we ignore this result. + // This can happen if you passed a class to function component, or non-function. + if (s !== 1 || c !== 1) { + do { + s--; + c--; // We may still have similar intermediate frames from the construct call. + // The next one that isn't the same should be our match though. + + if (c < 0 || sampleLines[s] !== controlLines[c]) { + // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. + var _frame = "\n" + sampleLines[s].replace(" at new ", " at "); + + { + if (typeof fn === "function") { + componentFrameCache.set(fn, _frame); + } + } // Return the line we found. + + return _frame; + } + } while (s >= 1 && c >= 0); + } + + break; + } + } + } +} finally { + reentry = false; + + { + ReactCurrentDispatcher$1.current = previousDispatcher; + reenableLogs(); + } + + Error.prepareStackTrace = previousPrepareStackTrace; +} // Fallback to just using the name if we couldn't make it throw. |