-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
*Blocking Issue*: Change detection after error creating infinite loop #17010
Comments
Please provide a plunker so that we can have a reproduction case. |
@mhevery: unfortunately, after spending 4 or 5 hours trying to reproduce this in a Plunker, still not able to. For now, I have a hack in place in my error handler to track the last error, and if the last stack matches the current error stack, I grab the ApplicationRef and call tick() on it, which triggers the check in tick() to prevent recursive calls to it. This breaks out of the infinite error loop and at least stops the browser from hanging with full CPU use. I've used breakpoints in the error handler and tried to go down through the stack trace, but it's very hard to figure out what is going on because everything in the trace is either internal to Angular, SystemJS, or Zone. It also doesn't help that there's a lot going on during the initial load (bootstrapping, routes being resolved, templates being loaded and compiled, etc.). The related issues all seemed tied to triggering change detection in a custom error handler. So I'm still fairly sure this has to be some subtle bug introduced in #16426, simply because even if I take out my custom ErrorHandler completely, the issue still occurs. And if it is somehow an error in my own code, I think that needs to be addressed in some way too. I can understand that if someone keeps manually triggering change detection in their error handler, there's not much the framework can do about that. But beyond that, it shouldn't be possible for a missing template variable to throw the framework into an infinite error loop. I'd like to help narrow this down so that I can try again to create a Plunker repro case. Can you (or anyone else) think of any situation I could be causing that would trigger an infinite error loop simply by referencing an invalid property in a component HTML template (other than triggering change detection in the error handler, which can't be the problem in this case)? |
I spent another 4 or 5 hours tonight trying to track this down, and have a few updates:
I'm fairly sure it has to be related to the async processes being triggered through the component hierarchy during creation, because if I comment out the children or stop the async processes from firing, there is no infinite loop of errors. I just get the single expected error. I'll try to spend more time on it over the weekend and see if I can get it replicated in a Plunkr. If not, I can try "sanitizing" my app and zipping it up as a repro case. |
@mhevery OK after a lot of frustrating trial and error, I think I have tracked down the problem. Here is a repro case. http://plnkr.co/edit/cXEvOObHAlmXer4HVtr4 The culprits seem to be having an initial error (e.g. property not found) and using Obviously, having this scenario totally lock up the browser seems like a big problem. Especially given how insanely time-consuming it was to track down the apparent source of the problem. This particular issue may also reveal some wider set of scenarios that weren't accounted for when the "post-error change detection" changes were made in 4.1.1. Let me know what you think or if you have any questions. Thanks. |
I was wrong, the infinite loop occurs whether |
@mhevery not trying to pester, but just wanted to check whether my Plunker adequately shows the problem? Just making sure, since right now I'm stuck on version 4.1.0 until this gets resolved or a workaround is found. |
I'm having the same issue. Another thing I've noticed is that if the errors happens after the application has started and not in the first route (for example, the landing page loads ok, but the user clicks a button that uses routerLink to another page), the infine loop do not occur, but the ErrorHandler is called twice, the second time with the message: 'Uncaught (in promise): ' + the original stacktrace. If I use version 4.1.0 all is good. |
@mhevery (or anyone else), I spent more than 20 hours tracking down this bug, so it would be nice to get a response here. Thanks. |
Same here using 4.2.3 |
@brian428 Thanks for providing the plunker! I looked into it, and am seeing the following:
To clarify:
Having said all of this, you can restore the old behavior of disabling the change detection of components with errors by adding the following code to your
Some notes about this workaround:
To summarize:
|
Thanks, I was not aware of that workaround and it's definitely not something I would have figured out myself. I'll try that to see if it helps. Since I'm really only modifying templates in dev mode, this may deal with the problem "well enough". To be clear, I've also seen cases where Angular does literally go into an infinite loop of errors, regardless of moving the mouse. So there's probably more going on (either in Angular or in the 3rd party code triggering the problem). I just spent so long tracking this down that I thought identifying the listener problem would be enough to get someone on the right track since it seemed to capture at least part of the problem. Even if this works "as expected", it still seems like a problem. I totally get that an infinite loop might be unavoidable if something throws an error, and the error handler itself triggers change detection that throws another error. But that's not what's happening here. I'm not sure how to say this properly, but it seems like the post-error change detection should really only become active after the initial component tree finishes its initial rendering? In other words, if something goes wrong while the page is initially being rendered that stops parts (or all) of the app from even being created, aren't we already way beyond the idea that a user could "keep using the app"? In this case, the app isn't even being initially rendered. So "continuing to use the app" isn't even an option. In any event, I'll see if the workaround you gave is enough to bypass the problem, at least in dev mode. I'll report back once I've tried it out. |
This should find a way into the documentation somehow, because this will hit anyone who is using a non-existing variable in a template, if I got it right. |
This bugs us daily, and when a dev forgets to turn off Airbrake.. it literally gets filled with exceptions. Anyway, even without that, it still makes it hard to close the browser, and we usually must kill it. The normal My assertion is that If this works as expected, the expectation is wrong. This is a problem and slows down development. Thank you @brian428 for chasing this so hard! |
@swftvsn I would agree. I've added the manual change detector detach workaround to my error handler. As indicated, it seems to work in dev mode. But it really seems like this is an issue that should be more thoroughly addressed. I would argue that it should be extremely difficult (ideally, impossible) to throw the framework into an error loop where the error handler keeps getting called repeatedly. Yes, this workaround works in dev mode. But what about a live server using prod mode? Something as trivial as an invalid property call in a template should never be able to lock the browser. Angular can't prevent the developer from writing bad code, like an infinite while loop, that has nothing to do with the error handler. But if the error handler is handling an error, the framework should be doing everything it can to prevent it from freezing the browser. I'm not sure what the optimal solution would be though. Only do post-error change detection if the initial component tree has finished rendering? Some error counter that clears itself on an interval, which stops change detection if too many error handler calls are made within a short amount of time? |
Is there any progress on this?
which comes from server. And sometimes server sends
then i am starting to receive inifinite error loop with |
I am running into this as well, but only when I've extended the built-in $exceptionHandler with a decorator, and not on all errors. |
This is bugging me too. I only get the behavior for template errors and when using NgZone in the custom error handler; which I have to do in order for the error handler to always show a This SO post suggest using NgZone - which works for most errors, but causes this behavior for template-related errors: https://stackoverflow.com/questions/49474788/angular-material-snackbar-and-custom-errorhandler-to-notify-error |
@vincentsels , same behavior here. I created a stackblitz to reproduce the problem: https://stackblitz.com/edit/global-error-handler-problem?file=src%2Fapp%2Fapp.component.html Any idea to solve this? Tks! |
Angular team ignores most important things.... |
@devversion seriously, this issue deserves WAY more attention that it's getting. |
same issue .... haiz |
We have the same issue. ErrorHandler opens a MatDialog in an NgZone which throws an error, bam infinite loop and browser lock. If we do not run MatDialog in an NgZone then it does not render properly and can not be closed. |
I've had to ditch using Rollbar because any user errors cause me to spam the hell out of their API, using up my account limit. @kara can we get some sort of response here? |
I decided to turn rollbar back on, within 24 hours I overwhelmed the error limit. @mhevery @matsko @angular would it be too much to ask, for a definitive answer on this? Considering how it results in the spamming of errors to error reporting systems, how on earth isn't this considered a priority? No instructors on how to mitigate it, or tweak a setting in the Angular engine to stop attempting to render a template after the nth error. Literally gone backwards from Angular 1 in this respect. I don't understand how the Angular team can neglect such an important aspect of the framework like this. |
Tracking rollbar issue here: |
@jpike88 In the meantime can you not simply set a |
Any update on this thread ? I am also in the same state. Even if i do not have any template errors and if i use the globalErrorhandler + zone as follow
i see that the applciation enters an infinte loop and freezes the browser tab. Also in my case i do not see this errors in chrome rather only in IE11. My error trace It would be great if there are any officially confirmation on the issue and a temporary workaround as it is very annoying blocker issue. |
A temporary fix I came up with was to rethrow the For example: handleError(err: any): void {
...
if (err instanceof TypeError) {
// Fallback to console logging.
console.err(err.message);
console.err(err.stack);
throw err;
}
...
zone.run(() => { ... } );
} Hope this helps anyone. |
Still no answer on this?? I'm fighting change detection on my ErrorHandler almost daily! If I have any kind of template error, it goes into an infinite console.error loop and I have to force close the browser to exit. None of the ngZone or changeDetectorRef workarounds are working for me. I honestly can't see how this isn't priority #1 on the Angular team??? This happens to me on every single project! |
Incase if someone is in the same pickle, Using runGuarded() instead of run() solved the issue temporarily for me. Read about the api here: |
I think this should be higher than My current workaround:
This though has the limitation of hiding actual multiple occurrences of the same error. |
This solution halts exceptions after limited amount of time but it does affect UI after halting errors. Is there a way that we can re-render UI after the errors are done producing? |
I have a relatively good solution for this. Use rxjs debounce and distinctUntilchanged!
this method disables change detection ( you can pause! ) but keeps usability by turning it back on after handling the error. Since I implemented this, template errors have stopped freezing my laptop, and chrome task manager is no longer needed. many Thanks to this issue's participants for the change detection idea, it has the same issue of not working in production, but the debounce will work. |
Hello, I am finding when there is a connection lost the infinite loop of the task kicks in and floods the console. Is this issue ever going to be addressed? |
See that omarmeky? Your remark was adressed, not even 6 months later. The stack overflow causing issue that exists in angular's core module is: an inconvenience no more! |
I am having a similar infinite loop issue when an error happens and is picked up by my global error handler:
When it tries to do the router navigate, it would loop and throw thousands of console logs at the top of the handleError function. |
This happened to us as well. Unfortunately, it is relatively hard to provide a small, reproducible example. In our case, we were attempting to send the error details to our logging service through an http call. Could that be the source of the problem? |
@miensol yes, this is very likely the source of your infinite loop |
I've tried that. However, it turns out that my error handler is already called inside |
it's 2024 and this is still one of the most problematic issue in Angular, definitely need to be addressed |
Goodnight. Any updates on this issue? Thanks. |
I'm submitting a ... (check one with "x")
Current behavior
Possibly relates to #9531 and #16426. Since the change to continue change detection after an error (4.1.1), I'm getting an infinite loop of errors if there's a problem with template parsing (such as a bound variable doesn't exist). It causes the browser to completely hang, and the browser process must be manually killed.
The console shows the infinite errors like this:
If I add a breakpoint in my error
handleError()
method, I can get a stack trace which may help with diagnosis. Since it is long, I'll attach it rather than embed.angular error loop stacktrace.txt
The issue is not my error handler triggering some sort of change detection, because I can completely remove the custom error handler class and the issue still manifests.
If you look through the stack trace, you can see that everything going on is internal to Angular, SystemJS (maybe it keeps trying to make XHR calls to load files, which triggers change detection?), and/or Zone. I'm not sure yet if it has to do with the fact that this is happening during bootstrap, or possibly something related to Zone.js, or something related to SystemJS.
Expected behavior
The browser should not completely hang due to something as basic as a template compilation error or binding error.
Minimal reproduction of the problem with instructions
I'm trying to create a Plunkr, but there are a number of pieces to put in place to mimic what's going on, and it is slow going. I'll keep trying.
Please tell us about your environment:
Windows 2010 x64
Angular version: Angular 2.1.3, Zone 0.8.10, System 0.19.41.
Browser: all
Language: TypeScript 2.3.2
The text was updated successfully, but these errors were encountered: