-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make console.error (and warn?) log a stack trace and codeframe like thrown errors do #8819
Comments
@kentcdodds Thanks for filling the issue. I wonder how did you manage to have such a nice stack trace (without any sort of filtering) that shows correct test file right away. When we initially fiddled with it, there was a fairly long stack to be useful and we had very similar console hijack there. Does Error.stackTraceLimit = Infinity
const origError = console.error
console.error = function(msg) {
if (/react-wrap-tests-with-act/.test("" + msg)) throw new Error("missing act")
return origError.apply(this, arguments)
} |
No, that's just what I was doing in my example. If it were to be built into jest, then it would be done completely different. The length of the stack trace will certainly differ based on the scenario. It'll be as long as it is 🤷♂️ My example was a pretty simple component. I'm not surprised that you have a long stack trace with an abstraction like mobx. This is why the dimming of lines that include the text |
In the general case, I think this sounds like a good idea. Might be noisy, but maybe not 🙂 We already collect a stack, although we only keep a single frame. Expanding that to keep all frames and construct a visual code frame should be straight forward (happens here: https://github.com/facebook/jest/blob/0d4834427f66091f403964c9be86a71d50a9f965/packages/jest-console/src/BufferedConsole.ts#L51). Semi related: #8790 Will it still work for async (concurrent?) React? Unless the logging happens synchronously I think we'll lose the real stack. Maybe one could configure /cc @threepointone EDIT: I see this was discussed in the React repo already. I still think having EDIT2: It's the reporter's responsibility to actually print the |
I already do have a "hacky" solution in user-land. I could make it into a separate package, but that kinda beats the point that user seeing that warning wants it to be helpful right away and not to look for some module or tool to improve error message. Since React doesn't want this, RTL doesn't want it either, then I guess Jest is only place left so I have my hopes here :) |
Getting a stack trace when logging works ok-ish for synchronous updates, but not at all for async updates. I tested with an apollo component at work now, and not a single line of user code is available in the stack. The code that updates the component is triggered by an observable (https://github.com/apollographql/react-apollo/blob/3e0a436561de1b37358166d4e9a4e14af5a94693/packages/hooks/src/data/QueryData.ts#L283) and the stack trace in its entirety is in |
This is how React does it https://github.com/facebook/react/blob/master/scripts/jest/setupTests.js#L69-L128 Works well for us |
Yeah, something like that works for sync logging, but the trace is not necessarily useful for asynchronous logging. Might still be worth building something like that into Jest, of course |
@threepointone That's somewhat sad that you have to "hack" React instead of supplying proper solution into React :/ |
Don't we have the exact same problem for async errors though? And we seem pretty happy with that anyway 🤷♂️ |
That's a fair point. I'm down with adding support for code frames in log messages, but I think it should be behind a config flag, and for all /cc @thymikee @jeysal @scotthovestadt thoughts and that (and the issue in general)? |
I would argue it's needed for all console types. From practice, the Unless of course some sort of filtering would be applied. I think it makes total sense to start at first frame that is out of Or make it configurable for each log level, although people with CRA would be unable to change it anyway 🤷♂ |
Right, which is why I think it should be opt-in, but I think per-level config is overkill. You can use a custom reporter of that's what you want, as the reporter would still control what to output and what not to. Whether or not CRA allows you to configure that is orthogonal IMO - if it's useful they'll add support for it
We'd probably use the same filtering we do with errors now, which removes all of jest's internal stuff and tries to find the topmost line in user code for the frame itself |
I think it would be a mistake to do it for all console methods 😬 like @FredyC said, console.log is a common workflow method people engage in and it could get very noisy very quickly. It's unlikely that if there's a console.log I don't know what called it. The benefit of console.error/warn is that they typically exist in dependency code and are unexpected so require some debugging to determine the root cause. |
I think this is a good idea. I'm wondering how common it really is to permanently have console output written during a test run. Pretty much every project I've seen so far makes sure tests do not log because even without stack traces they mess up the output in an annoying way. Exceptions being some small projects with just a few test files, and of course temporary log statements inserted while debugging that won't be committed. If this perception is correct I don't even see the need to make it opt-in. Side note: The opt-out could be a generalization of |
Agreed. Typically |
Also, I agree that this should be automatic and opt out with |
I had entered #8819
`PASS test/ui/admin/ahanges.parallel.test.js (25.328s)
b) Logs getting interleaved (Undesirable for us and it's good that jest currently doesn't do this): 2019-08-09 15:30:55 WorkerID:3 info: Updating app session via API 2019-08-09 15:30:54 WorkerID:1 info: Login Page - Entered username: 2019-08-09 15:30:55 WorkerID:3 info: Navigating to: https://engineering-zzz 2019-08-09 15:30:55 WorkerID:1 info: Login Page - Entered username:` I see above there was conversation around console.logs not being used much - we actually use it quite a bit along with console.warn and console.error as well. I want to make sure that with the changes agreed to in this ticket it doesn't break jest's current behavior of consoleBuffering when multiple tests are run. Also, this feature is already used in jest-junit jest-community/jest-junit#45 so another reason for not breaking this feature. So essentially current jest behavior as described in 2 a) is preserved. |
Doing this only for |
Hello @gaearon , I am interested to work on this issue. Can you please help me getting started. Thanks :) |
Since this is targeting Node, I would recommend Simplified example: console.error = function consoleErrorWithStack(message) {
const error = {message};
Error.captureStackTrace(error, consoleErrorWithStack);
// error.stack will not include consoleErrorWithStack
doRealLogging(error.stack);
} (EDIT: Fixed the example.) I believe Jest filters stack traces anyway before displaying them, but it's probably better to avoid adding unnecessary info than rely on filtering to remove it. |
Hi @ParthS007 are you working on this issue? If not, I have some clues and would like to try to solve it. |
Hey @ychi , I am currently reading all the comments and just understanding whats needed to be done here. |
@ParthS007 Just a heads up this might not be necessarily the most beginner-friendly issue. Please feel free to dig into it but I think we shouldn't hold off progress on fixing this if someone else wants to work on it too. |
Thanks @ParthS007 & @gaearon. I will take it. Hi @SimenB Two questions would be:
It makes reading easier, and react prints message before stack in
|
We have a util for formatting errors that attach a code frame already, I think it makes sense to reuse that: https://github.com/facebook/jest/blob/677b763ec0a8c592c7395901c8efa1491c138c61/packages/jest-message-util/src/index.ts#L248
|
One challenge I noticed is that
Since there are a number of test result formatters in |
Seems reasonable. |
I agree it makes sense, but it's also technically a breaking change. We could duplicate it over though, and only break it in v26 |
Hi @SimenB, I have another question: in
|
In order to capture the stack trace in a 'source-mapped' flavour, I think it might make sense to extend (or duplicate, to avoid breaking change) the following function so that it return Or maybe even add a function that dedicated to this task.
Would that bring any concerns? |
I've removed the dependency on |
Released in 25.4.0, please try it out 🙂 |
Is there a corresponding |
Next release will respect |
@SimenB I am looking at the Jest 26 docs and am not seeing a config option for |
@SimenB any updates about this? The current release still doesn't have it in the config, and we'd like to disable it as it is much too noisy for our tests. |
@SimenB: I think it's because the global config not passed down to |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
🚀 Feature Proposal
99% of the time, if
console.error
andconsole.warn
are called during tests (and they're not mocked), it's something that needs to be fixed.Motivation
In particular, with React's new
act
warning, people are seeing output like this:It's not entirely helpful. It does show that this is happening in the
User
component, but there could be any number of places within that component that could have triggered that error to be logged.Example
Here's a proof of concept of what I'm suggesting (definitely wouldn't work like this if built-in):
This would look like:
And visually:
And it could be potentially improved within Jest so it's even more helpful (with color coding to highlight the part of the code that triggered the error). Similar to when an error is thrown.
And visually:
To be clear, what I mean is that
console.error
could print out a stack trace and codeframe where the part of the stack trace which is not in user code could be dimmed to reduce confusion and the codeframe would show the part of the user's code which ultimately triggered the error to be logged.Pitch
I think this would help more than just
act
and it seems like the correct place for this to happen. It would help people get rid of error (and potentially warn) logs quicker, and move on to building their apps faster (which I believe is the goal of Jest).Reference: testing-library/react-testing-library#434
I'd love to hear what you all think!
The text was updated successfully, but these errors were encountered: