From 3c54df0914f02fed146faa519a5a899d0e3af32e Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 17 Dec 2019 15:21:18 +0000 Subject: [PATCH] Fix missing stacks in WWW warnings (#17638) --- packages/shared/consoleWithStackDev.js | 2 + .../shared/forks/consoleWithStackDev.www.js | 46 +++++++++++++++---- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/shared/consoleWithStackDev.js b/packages/shared/consoleWithStackDev.js index 22bbfee86766e..ee4dea5a5d86c 100644 --- a/packages/shared/consoleWithStackDev.js +++ b/packages/shared/consoleWithStackDev.js @@ -26,6 +26,8 @@ export function error(format, ...args) { } function printWarning(level, format, args) { + // When changing this logic, you might want to also + // update consoleWithStackDev.www.js as well. if (__DEV__) { const hasExistingStack = args.length > 0 && diff --git a/packages/shared/forks/consoleWithStackDev.www.js b/packages/shared/forks/consoleWithStackDev.www.js index 09c8f7fba7f71..5389f638663b8 100644 --- a/packages/shared/forks/consoleWithStackDev.www.js +++ b/packages/shared/forks/consoleWithStackDev.www.js @@ -8,15 +8,43 @@ // This refers to a WWW module. const warningWWW = require('warning'); -export function warn() { - // TODO: use different level for "warn". - const args = Array.prototype.slice.call(arguments); - args.unshift(false); - warningWWW.apply(null, args); +export function warn(format, ...args) { + if (__DEV__) { + printWarning('warn', format, args); + } } -export function error() { - const args = Array.prototype.slice.call(arguments); - args.unshift(false); - warningWWW.apply(null, args); +export function error(format, ...args) { + if (__DEV__) { + printWarning('error', format, args); + } +} + +function printWarning(level, format, args) { + if (__DEV__) { + const hasExistingStack = + args.length > 0 && + typeof args[args.length - 1] === 'string' && + args[args.length - 1].indexOf('\n in') === 0; + + if (!hasExistingStack) { + const React = require('react'); + const ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + // Defensive in case this is fired before React is initialized. + if (ReactSharedInternals != null) { + const ReactDebugCurrentFrame = + ReactSharedInternals.ReactDebugCurrentFrame; + const stack = ReactDebugCurrentFrame.getStackAddendum(); + if (stack !== '') { + format += '%s'; + args.push(stack); + } + } + } + // TODO: don't ignore level and pass it down somewhere too. + args.unshift(format); + args.unshift(false); + warningWWW.apply(null, args); + } }