-
Notifications
You must be signed in to change notification settings - Fork 123
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
RFC Trap handle non terminating errors #182
base: master
Are you sure you want to change the base?
RFC Trap handle non terminating errors #182
Conversation
I like the idea of these constructs being able to handle both terminating and non-terminating errors. However, why would we create a disparity here? There are very good reasons Use of trap should not be encouraged over try/catch in my opinion. Once a trap statement has been declared for a scope, you cannot simply "remove" the trapping functionality from that scope. We should aim to apply this to I do however very much like the idea of adding such a property to ErrorRecord; it's long been missing, and it's a very welcome addition. It's not clear to me if changing the errors caught would be inclusive or exclusive. Does this aim to replace or add on to the existing functionality? I.e., if I use this feature, will I ONLY be catching non-terminating errors now, or will I catch both? Should we allow users to select one, the other, and both as a third separate option? |
@TylerLeonhardt I think there needs to be a |
Sounds good. If I have some downtime on my travels I'll add something. |
/cc @mklement0 for information. |
Without a broader vision or story describing the plans to fix error handling/exception handling in PowerShell, this RFC seems premature. At face value this feels like it just continues a game of cat and mouse: first we get trap, then try/catch, now trap wants to do more than try/catch can, and so on. Plus, ugh, you want the PowerShell community to go from using try/catch back to trap now, really? A few other random thoughts on this:
FWIW, the only use I have found for the |
More food for thought for this RFC and Issue #6010:
|
To sum up what I suggested above (plus adding some related info):
If you'd like me to take a kick at such an RFC (or RFCs if you want multiple, with them referencing one another since they are related), let me know. |
I don't see there being a hard wrong or right here. I think some context might be helpful. Changing the behaviour of The original problem was specified in PowerShell/PowerShell#6010, where @jpsnover suggested a parameter to provide a scriptblock as a continuation to invoke when errors or any kind are encountered. He particularly had in mind long-running distributed services where interaction is not possible; there are scenarios where logging is the only real solution and nothing handled the case of needing to log and then keep going (i.e. not stop the pipeline) when a non-terminating error is encountered. (Well almost nothing -- another possibility would be something like Looking at this we realised that wrapping every single statement in It's well known that PowerShell's error behaviour is tortuous, but fixing it would probably break a very large number of scripts which I think it's in PowerShell's interest to maintain compatibility with. (I know the RFC proposes breaking |
|
||
## Alternate Proposals and Considerations | ||
|
||
### Introduce a `trapall` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My personal preference is trapall
, since:
- It doesn't break the existing behaviour of
trap
- It isn't a syntactic break;
trapall
will still parse and execute, but will just throw when the statement invokingtrapall
is hit in older PowerShell verisons. Compare this totrap -NonTerminating
which will not parse in older PowerShell versions. This means you can wrap the former in a version condition and it will still work cross-version.
We might even able to carefully define trapall
so that ICustomAstVisitor
isn't broken, by reusing the TrapStatementAst
type with a new parameter in the constructor detailing whether it's a trap
or a trapall
statement.
I think these are very valid concerns, but one thing I think should be stated is that there are two opposing design desires here:
If I were designing things from scratch, I would imagine an error handling specification should work like CSS where the most specific definition wins, and when that's ambiguous, the last defined. But I think we've got too much backward compatibility to bear to rearchitect that. |
Eh, I don't think enhancing only trap is the solution. I mean, try/catch already allows the use of the If we enhance trap in the suggested ways, it doesn't make sense not to also enhance try/catch in the same way, in my opinion. All you create is confusion at the outset because these two constructs have up to this point been identical in their capabilities. Once that hurdle is overcome, then we also are introducing huge maintainability problems to come by encouraging the use of trap. Trap unconditionally diverts the flow of execution across the entire torrent scope when an error occurs. A single trap statement inserted at any point in the code can drastically change how execution in handled. In any sufficiently large script, this becomes a maintainability problem, because there is no clear indicator of how an error at any given point will be handled. Try/catch is generally favoured because it is crystal clear what portions of code are covered by it, there's no guesswork. Creating a scenario where trap is more capable than its counterpart is a very bad idea in my opinion as it encourages very difficult to maintain coding practices that simply do not scale well at all. |
@rjmholt Thanks for the details. I had most of that background already. I don't believe that changing trap is the right solution. Nor do I believe that changing try/catch is the right solution either.
That's a very misleading statement. I believe there are significant changes that can be made to PowerShell's current error behavior (which I would hardly describe as tortuous...onerous, maybe) to fix a lot of the difficulties without introducing breaking changes whatsoever. By stating that it just can't be done sounds like you guys are just washing your hands of making that effort to get it fixed. What's tortuous is that it's taking this long to get those important issues resolved. |
Co-Authored-By: Robert Holt <[email protected]>
I'm still on vacation (which is why I can't add more details to the RFC just yet) but I wanted to enforce the reasoning behind this RFC as stated in this RFC:
@KirkMunro I don't see your suggestion to the
I tried this and this doesn't seem to be true. Spoke to Joel about it and he thinks he was assuming that was the behavior because If we go down the |
@TylerLeonhardt I read the purpose statement, but I still disagree with this RFC. The timing of this RFC is wrong (there are other very closely related problems that should be solved before this problem is even considered). There is no overall vision or story that clearly articulates the specific problems that make error handling difficult to work with in PowerShell, so that each of those problems can be considered when making any investment in how PowerShell deals with errors, which creates a significant risk that this RFC, if implemented, will just be adding to the pile and not getting to the crux of the issues with error handling. There are other error handling issues/discussions that should happen first. Another area of significant risk/concern for me with this RFC is that it blurs the line between terminating and non-terminating errors even more (the other source of blur is how PowerShell treats terminating errors as non-terminating unless wrapped in try/catch), and I don't think that line should be blurred at all. Executing beyond a terminating error should require intentional code, not accidental, and I'm afraid if this RFC is implemented we'll see even more mishandling of terminating errors than we already do today. With those concerns I have, my reason to push back on this RFC is that it takes scarce attention and resources away from the other issues/discussions in this area that really need to happen first, while risking just throwing more wood onto the fire at the same time. I don't have confidence that you guys are really looking at a broader scope for how errors are handled in PowerShell. I really wish I did, but with this RFC coming out, I'm afraid I just don't. |
@TylerLeonhardt PR #187 is my attempt at what should be done to fix much of the error handling in PowerShell, in ways that I talked about above. Note that there are four RFCs in that PR, all related to one another in some way. I think these are tackling the more important problems, while still working on the original issues that started you looking at in this RFC in the first place. |
Seems to me that we have not set expectations very well in regards to error handling. This is creating--and getting in the way of solving--many of the problems. For a moment I'm going to ignore all backward compatibility and do some brainstorming. How is this situation handled in other domains? Don't all of them do this the same way as each other and differently than powershell? In other languages Terminating Errors and Non Terminating errors are called different things. One of them is so important that the current process should stop running and the other is no less important but the caller only needs to be notified of a problem without stopping. These are two distinct workflows. python, bash, perl, you name it. Errors NEVER terminate. Terminations ONLY come from explicit commands such as throw, raise, and exit. The interpreter blowing up is a different issue but yes that stops the program from running too. Yeah, I think errors should never terminate in powershell. That model is working pretty well for everyone else. $ErrorActionPreference would not be needed. The only way to eliminate the guesswork is to have the user explicitly use a command that terminates or not. Use write-error to record an error but don't stop. Throw an exception to stop immediately and catch where appropriate. If we eliminate terminating errors we don't have to 'handle' them any different than 'errors' which is what the RFC is calling for. What about calling non powershell code? All of the commands and programs we call using powershell can't throw. I call some old DOS utility to format the disk and it can only spit out text and return an integer. Handling errors from non powershell commands is one of the things I spend the most time on but that seems like a different problem than error handling within powershell itself. If I am calling an external utility I usually wrap it in try/catch and throw when I get bad results. Could this be implemented with backward compatibility? seems unlikely given the mess that is powershell error handling and the expectation that ErrorActionPreference = 'stop' will actually work sometimes. I suppose backward compatibility might be possible with $errorActionPreference = 'never'. The problem is exacerbated by having to use try/catch around any piece of code that should be allowed to throw. Anyway, I'm done rambling. |
Adding
ErrorType
property toErrorRecord
and makingtrap
s handle non-terminating errors as well.The purpose would be to offer a single solution to handle both terminating and non-terminating issues