You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
When should you write an error if you have no output? #113
@PowerShell/powershell-committee discussed this and we also discussed it in this morning's Community Call. We agreed that the intent is that if a literal is passed and is not found, it should return a non-terminating error. Cmdlets that don't have this behavior have bugs.
In cases where it's explicit or implicit filtering, it should return nothing.
The real issue is that we are missing Test-* cmdlets so users had to rely on current behavior with Get-* cmdlets to see if something exists and we should add those cmdlets in the future.
Here is the clearest, most obvious counter-example I can think of right now: Get-AzureKeyVaultSecret
I use this command because it's one that has a few easy to understand use cases and specific issues that lead to a specific design (in my opinion). It has a few parameter sets:
If you don't pass a name, it will output ALL the secrets
If you pass a name, it will output only that one secret (the latest version of it, or a specified version of it), except ...
If you specify -IncludeVersions (instead of a specific version) it will output the entire history of the specific thing
You can extend your search to deleted items
In each case, if it doesn't find a matching value, it quietly returns nothing. I consider that to be the best possible design, because:
As a web command, it's likely to encounter connectivity problems, resulting in terminating errors
As a command that accesses data that is secure and has access controls, it's likely to encounter permission errors even when the data exists.
However, any time you're looking up an item by name, it's very likely that the value doesn't exist (yet). If the command produced an error for the "everything worked fine, but there's nothing to return" case, I believe it would be extremely complicated to use correctly, and would generally result in careless or inexperienced users hiding the important errors.
Error handling for these cases is terrible
The first time a user calls the command and it returns a trivial "not found" error, they might choose to suppress that error by adding -ErrorAction Ignore or SilentlyContinue and would then miss out on the errors that are actually important (i.e. connectivity problems, or access errors like "Operation 'list' is not allowed by vault policy").
A design which produces errors for missing values forces careful users to capture the error and check which error it was. In fact ...
if the error is not terminating, it's even worse than if it were terminating like the others.
In order to suppress a non-terminating error, you must use -ErrorAction and either:
set it to SilentlyContinue (which also suppresses terminating exceptions) and capture the error, test the result, and throw if it's not the simple error
set it to Stop and wrap it in try/catch in order to test the error type, ignore the "does not exist" error and rethrow the rest.
However, even if the command simply throws a different unique exception for each use case (or writes an error with a different unique error category), producing an error in this situation results in the user needing to explicitly handle the error or avoid it ...
In order to allow you to avoid the error, the PowerShell Committee's proposal essentially requires every Get command to have a Test command.
For expensive commands, I'm afraid this this is a terrible idea
If Get-AzureKeyVaultSecret wrote errors for missing entries and had a separate Test command, then in order to avoid the very complicated error handling for the Get command, you would need to instead wrap your Get call in a Test call.
The problem is that the Test call would require the same slow and heavy round-trip, authenticated network request, and would still have all the same exception cases for access and networking errors.
Worse yet, you're not just making TWO requests when you could just make one -- it's actually the exact same request each time, because there's no REST method for "test" so you would be calling the GET method for Test and for Get ... returning the full data each time ...
Reacted by Tim Curwick, Rob Sewell, Chris Gardner, Shawn Melton, Warren Frame and Mike
I don't think Get-ChildItem EmptyFolder is in question here. What the PS committee says is this:
We agreed that the intent is that if a literal is passed and is not found ...
Well, EmptyFolderwas found but it was empty. So this proposal does NOT suggest that this scenario should generate a non-terminating error. However the following does error:
PS> Get-ChildItem xyzzy
Get-ChildItem : Cannot find path 'C:\Users\hillr\xyzzy' because it does not exist.
...
And I think rightly so. CMD and Bash also error in this case.
And while we're looking at these examples ... Get-Clipboard isn't a command on PowerShell Core and even on Windows PowerShell, it only takes switch params. So I'm not sure how it applies to this proposal. Get-Command -Verb build is a filtering command that doesn't error. Check. Get-Command xyzzy looks for a specific command and does generate a non-terminating error. Check (and good). Get-History does not error when you run it right after PS starts - when there is no history yet. Check. However it fails if you pass it an id that doesn't exist Get-History -id 8675309. Check (also good).
RE 1, this is a filtering scenario therefore it is behaving as designed - to not return a non-term error. Personally I'm not big fan of these "inherently filtering" commands. If I wanted filtering I would just specify Get-Module ModuleThatIsNotLoaded*. Then I would have more control (filtering or not). Also, there are cases where I want an error when a module is not found. Now, I have to generate that myself rather than rely on -EA stop. Oh well. Too late to make any changes to this command.
RE 2, doesn't error now and wouldn't error if implemented under the proposal IMO. The use of -ListAvailable makes this a filtering scenario.
RE 5, it would have been nice if this generated a non-terminating error IMO. Again would have been easy to avoid with Get-TypeData System.Boolean* or Get-TypeData System.Boolean -ea 0. But "probably" not worth changing at this point.
Back to the original question:
When should you write an error if you have no output?
IMO you error when you don't have the specific item I asked for and your design is to only return a single item i.e. not all things that match the term I specified. But please, require a wildcard char for filtering - that's what they're for. However, there are nuances here, I'll give you that. Like asking for the contents of a specific (empty) folder should not generate an error. Or asking for the "contents" of a specific (empty) file should not generate an error either.
they might choose to suppress that error by adding -ErrorAction Ignore or SilentlyContinue and would then miss out on the errors that are actually important (i.e. connectivity problems ...
Just because a command writes non-terminating errors doesn't mean it can't also throw terminating errors. A connectivity problem should result in a terminating error since there's no way the command can proceed.
should not return an error when there is nothing there
why should
Get-Command NoneExisitngCommand
return an error when there is no command of that name?
I have asked for this particular command and I have received an error rather than either
a, Here is precisely what you asked for - nothing
b, A more useful message to the user than a full error message
I disagree that this should be an error. I also find that it confuses newcomers. An error and a sea of red text means something is wrong and in this case nothing is wrong, it just doesn't exist.
Personally, I want it to return nothing because there is nothing to be returned. I would be happy with a warning but I see it as a direct question that should be return in a pedantic manner.
"Give me all of the Printers named foo please"
"Here are all of the printers named foo "
Funnily enough 5 minutes afer writing this I find another example that maybe also explains why I see it his way. This is what I get with the virtualmachinemanager module right now too.
Give me all of the Virtual Machines named $Vmname
(There aren't any - we are cleaning up a system of old data prior to upgrade)
Which makes my coding easier and training the users easier also ;-)
It makes it easier for users at the command line and it makes it easier for error handling too as Joel mentions above more eloquently than I can.
@rkeithhill but you've ignored my argument in favor of picking apart the op examples. let's set all of that aside. Read my first reply, and explain to me how your logic applies to Get-AzureKeyVaultSecret (after that, we can talk about all these other examples from a point of understanding each other, rather than just defending the current behavior).
However, this comment seems like a HUGE misunderstanding, which in my opinion is the root cause of your point of view (and everyone who thinks these should error):
Just because a command writes non-terminating errors doesn't mean it can't also throw terminating errors. A connectivity problem should result in a terminating error since there's no way the command can proceed.
That's simply not reasonable. Take this sample command:
Are you saying that the user should just learn to ignore and live with the huge block of red from Write-Error, or do you have a magic incantation whereby they can suppress it without suppressing the exception?
@SQLDBAWithABeard then you should be disappointed in a lot of PowerShell Get- commands: Get-Variable, Get-Process, Get-PSDrive, Get-PSRepository, Get-PackageSource, Get-PackageProvider, Get-DscResource, etc, etc, etc.
I'm on board with what @Jaykul wrote up top. Tweet-sized:
I much prefer no error. Testing for absence is incredibly easy, can be used in various logic statements, is the same for every command. Looking for a specific error type indicating something isn't found? Ugly af, and IMHO goes against the tenets of PowerShell
The existing commands that follow the error-if-nothing-found convention are painful to deal with.
I don't understand why this is even up for debate. Do folks seriously want to create a common convention forcing everyone who writes PowerShell to handle multiple error types (which differ for each command, generally) for something that should (and often is, currently) as simple as testing for presence of a value? I realize some folks here are very experienced, but this seems like a bad idea that would affect the usability and desirability of the language for a large swath of folks, including myself.
I wonder if it is just the "sea of red" that so many folks have an aversion to that they're willing to not have commands error just to avoid it. I can certainly sympathize. We've tried in the past to argue for more succinct error msgs. I would love to see something like this:
PS> try { Test-Error -Error -Exception } catch {}
Test-Error : Test Error
For more details on this error run: $error[0]
<optional error hook to allow an extensible error message hint capability>
What I don't like about that is that the $error collection is a stack and that error index above of 0 is not stable. I'd like to see something more like this:
PS> try { Test-Error -Error -Exception } catch {}
Test-Error : Test Error
For more details on this error run: Get-Error 8c1c74a
<optional error hook to allow an extensible error message hint capability>
where 8c1c74a uniquely identifies the error record and can be used at any time up until that error record is "aged" out of the $error collection. That would look like:
Also, with Get-Error, I'd like to see a -Verbose parameter where I could get extended error details - much like the Resolve-Error (in PSCX) command provides:
Do folks seriously want to create a common convention forcing everyone who writes PowerShell to handle multiple error types
Yup. Although the "forcing everyone" bit sounds ominous. Did you see that list I posted above? You already have to do this with many Get-* commands. Are you suggesting we should change those and incur breaking changes?
Also folks seem to be only considering the scripting case and not the interactive CLI case. I happen to believe that most folks using a shell expectGet-Item xyzzy to error - just not with a sea of red text. :-) It's been that way on Bash for decades, ditto for CMD.
@rkeithhill or others who are in the it should error when you request a specific item and that item is not found - can you spell out a value proposition here? I'm struggling to see one. bash does this or some-random-command does this is not really a strong value here, IMHO, when this convention adds serious overhead
Given that the system temp dir is C:\Windows\Temp (and you are running elevated), what do you expect this to return:
PS> gci C:\Windows\Tmp
If this command were to return nothing, I would assume the directory is empty and not that it actually doesn't exist. That's not a good user experience.
@SQLDBAWithABeard then you should be disappointed in a lot of PowerShell Get- commands: Get-Variable, Get-Process, Get-PSDrive, Get-PSRepository, Get-PackageSource, Get-PackageProvider, Get-DscResource, etc, etc, etc.
Yes - when considering this subject.
Although I can work around it when coding or when at the command line I can read it. I have to explain it to many people who are intimidated by the sea of red. I always want PowerShell to be as easy as possible for all people
If there is a chance to influence the choice, my choice is for no error if nothing to return
Given that the system temp dir is C:\Windows\Temp (and you are running elevated), what do you expect this to return:
PS> gci C:\Windows\Tmp
If this command were to return nothing, I would assume the directory is empty and not that it actually doesn't exist. That's not a good user experience.
I think this is a poor example @rkeithhill GCI Folderthatdoesntexist is asking for the contents of a folder that doesnt exist so that should give some output
This command can be easily made to behave the way you want:
Get-Printer Doesntexist*
BTW I think you guys are tilting at windmills here. On my Windows 10 1803 system in an elevated Windows PowerShell (more commands built-in), I count the following number of get commands:
That's 71% of the built-in Get commands that do error when the specified item is not found. So even if you don't think the PowerShell Committee is right on this (and yeah, they do have a few years experience), I don't see them changing over to "not finding the specified item should not (non-term) error". That said, I do get @Jaykul perf argument for REST calls. But again, I think for new REST/remote commands like this, you just specify * to tell the command to not write a non-term error if the wildcard specifier results in no output.
Update: the above results are highly dependent on what modules you have loaded. And it also only checks Get commands with a Name parameter. I tried this again with the just following modules loaded:
This command can be easily made to behave the way you want:
Get-Printer Doesntexist*
I know that it can. But I am not just speaking for me but for the people who read all the blog posts where this isn't mentioned for all of the commands they use who are confused or have extra work to do when there is an error. Lets make it easier for people
From the original post
So I ask this community: is that right?
Should a Get command that takes a literal name always write an error when it does not return anything?
Pretend that PowerShell was green-field, and that whatever you decide here will not break existing code.
If it was green field this would be my view. In the beginning, it was a different view and now the choice has been suggested to have a different view also. I am ok with that, if that is the way the majority want it.
I am not doubting all the years of experience that PowerShell committee have but I would say that there are folk commenting here and elsewhere with plenty of years experience as well and their opinion is welcomed as well
Also - can I mention my Warning suggestion again ? ;-)
something* looks innocuous enough. Using it can be dangerous. How many folks do you think will consider all the implications of a wildcard?
This is the same deal with why we tell people to never, ever use ambiguous parameter names. What if somethingelse is a thing you shouldn't be matching?
You can just is a tempting refrain, but most alternatives I've seen here:
What if somethingelse is a thing you shouldn't be matching?
Fair point. I suppose this would be less than satisfying: Get-Something somethin[g]? :-) I guess there's no getting around some parameters inherently acting as filters.
My expectation and joy of powershell is that Powershell will only error when something is a problem. Powershell has a precedence of great use of errors that help lead scripters to an actionable solution. Not being able to find something does not provide an actionable solution. Null data is not an issue it gives you just as much information about the output as actual data. Embrace null data.
Hi all. I am new PS user, with not much of experience of writing PS code.
I've read the thread and I can agree with people saying: I looked for something, that something does not exists, do not return anything.
It seems more natural to me when you go to a store looking for a thing and it's not there (because it's not there, or you have wrong name of the thing). The result would be : not found, rather than error.
Sometimes lack of any message can be confusing as may indicate some other problem.
When we apply analogy to search/not-found there is usually something like:
"not found", "not matching criteria", "0 results"
But in many cases it would be Information or Warning, not an Error.
Initially I might want to see the message, rather then nothing, but it might change when I have more experience with PS.
That's from the user perspective. Hope you find it helpful.
I tend to call almost every command with either -ErrorAction Stop or -ErrorAction Ignore. I either care about the error and want to do something when it happens, or I don't care at all because all it really means is that I'm not getting the data that I want and can't do anything about it.
Any time I call a cmdlet that gets something, I have to check to make sure I got a value before continuing anyway. I kind of prefer to not return values over creating errors. I like to see errors as something unexpected. I expect that a get command will either get me something or it will not.
If we are talking green field here, I would require a Test- command for every Get- command that returns an error for no results. I want to be able to avoid errors, not suppress them or be required to handle them. If a Test- command does not make sense in the context of the command, then it does not make sense for the Get- command to generate errors for no results.
I am OK with GCI giving me an error on a missing folder because I can test for it. Only I can decide if a missing folder is an expected or unexpected situation.
Please read my reply here. In particular, I don't think we should be talking in terms of "always" or "never". There are good reasons why we have rules of thumb, and sometimes we have good reasons to break those rules of thumb.
@SQLDBAWithABeard: warnings are hard to handle non-interactively, and we don't want users depending on strings. Error objects allow script authors to handle error behavior deterministically and we're held to not-breaking that behavior over time.
We don't want to break existing scripts today, hence the revert. While I understand the desire to have a "what if this was greenfield" argument, that ultimately leads us towards an academic discussion that has little bearing on the real-world end result (which, in this case, is basically "leave our inconsistencies so that we're consistent with the past").
In general, I'm not super concerned about "painting the screen red" as long as we don't halt execution. That being said, I'm open to hearing about more scenarios where non-terminating errors are more painful than I'm understanding.
Agreed, our error output should be better.
Reacted by Keith Hill, Rob Sewell, Ryan Spletzer, Oliver Lipkau, Peter M Taylor and wisemoth
Re you're being "open to hearing about more scenarios where non-terminating errors are...painful...."
At my level, much of my code is within try/catch blocks with ErrorActionPreference set to Stop, so non-terminating errors don't exist. Adding complexity to the error handling to handle "expected" errors different from actual errors is painful. It is much easier to distinguish between an error and a null result if one of them is an error and the other is a null result, instead of them being two different types of errors, terminating or not.
And at the level of the junior scripters that make up the bulks of the community, any unnecessary complexity is painful, slows adoption, and steepens the learning curve. It should be possible to add complexity to do complex things, but default behavior should make it simple to do simple things.
@joeyaiello non-terminating errors are one of the most painful things in PowerShell, because literally at any time a caller of my code may change the rules by just calling my function with -ErrorAction Stop and suddenly they all turn into terminating errors ...
Activity
Jaykul commentedon Aug 21, 2018
Spoiler: I think this is wrong.
Here is the clearest, most obvious counter-example I can think of right now: Get-AzureKeyVaultSecret
I use this command because it's one that has a few easy to understand use cases and specific issues that lead to a specific design (in my opinion). It has a few parameter sets:
In each case, if it doesn't find a matching value, it quietly returns nothing. I consider that to be the best possible design, because:
However, any time you're looking up an item by name, it's very likely that the value doesn't exist (yet). If the command produced an error for the "everything worked fine, but there's nothing to return" case, I believe it would be extremely complicated to use correctly, and would generally result in careless or inexperienced users hiding the important errors.
Error handling for these cases is terrible
The first time a user calls the command and it returns a trivial "not found" error, they might choose to suppress that error by adding
-ErrorAction IgnoreorSilentlyContinueand would then miss out on the errors that are actually important (i.e. connectivity problems, or access errors like "Operation 'list' is not allowed by vault policy").A design which produces errors for missing values forces careful users to capture the error and check which error it was. In fact ...
if the error is not terminating, it's even worse than if it were terminating like the others.
In order to suppress a non-terminating error, you must use
-ErrorActionand either:SilentlyContinue(which also suppresses terminating exceptions) and capture the error, test the result, and throw if it's not the simple errorStopand wrap it in try/catch in order to test the error type, ignore the "does not exist" error and rethrow the rest.However, even if the command simply throws a different unique exception for each use case (or writes an error with a different unique error category), producing an error in this situation results in the user needing to explicitly handle the error or avoid it ...
In order to allow you to avoid the error, the PowerShell Committee's proposal essentially requires every
Getcommand to have aTestcommand.For expensive commands, I'm afraid this this is a terrible idea
If
Get-AzureKeyVaultSecretwrote errors for missing entries and had a separateTestcommand, then in order to avoid the very complicated error handling for theGetcommand, you would need to instead wrap yourGetcall in aTestcall.The problem is that the
Testcall would require the same slow and heavy round-trip, authenticated network request, and would still have all the same exception cases for access and networking errors.Worse yet, you're not just making TWO requests when you could just make one -- it's actually the exact same request each time, because there's no REST method for "test" so you would be calling the
GETmethod forTestand forGet... returning the full data each time ...SQLDBAWithABeard commentedon Aug 21, 2018
On phone so employing brevity.
I strongly disagree that there should be an error.
I see
Get-ChildItem EmptyFolder
As
Give me all of the contents of the folder.
If there aren't any don't return anything. It's not an error if it is doing what I ask.
I also think it is misleading as "an error" means something is wrong. Noth in ng to return is not "wrong"
TimCurwick commentedon Aug 21, 2018
I strongly agree with Joel.
Returning nothing when there is nothing to return is the appropriate response and not an error.
rkeithhill commentedon Aug 22, 2018
I don't think
Get-ChildItem EmptyFolderis in question here. What the PS committee says is this:Well,
EmptyFolderwas found but it was empty. So this proposal does NOT suggest that this scenario should generate a non-terminating error. However the following does error:And I think rightly so. CMD and Bash also error in this case.
And while we're looking at these examples ...
Get-Clipboardisn't a command on PowerShell Core and even on Windows PowerShell, it only takes switch params. So I'm not sure how it applies to this proposal.Get-Command -Verb buildis a filtering command that doesn't error. Check.Get-Command xyzzylooks for a specific command and does generate a non-terminating error. Check (and good).Get-Historydoes not error when you run it right after PS starts - when there is no history yet. Check. However it fails if you pass it an id that doesn't existGet-History -id 8675309. Check (also good).RE 1, this is a filtering scenario therefore it is behaving as designed - to not return a non-term error. Personally I'm not big fan of these "inherently filtering" commands. If I wanted filtering I would just specify
Get-Module ModuleThatIsNotLoaded*. Then I would have more control (filtering or not). Also, there are cases where I want an error when a module is not found. Now, I have to generate that myself rather than rely on-EA stop. Oh well. Too late to make any changes to this command.RE 2, doesn't error now and wouldn't error if implemented under the proposal IMO. The use of
-ListAvailablemakes this a filtering scenario.RE 5, it would have been nice if this generated a non-terminating error IMO. Again would have been easy to avoid with
Get-TypeData System.Boolean*orGet-TypeData System.Boolean -ea 0. But "probably" not worth changing at this point.Back to the original question:
IMO you error when you don't have the specific item I asked for and your design is to only return a single item i.e. not all things that match the term I specified. But please, require a wildcard char for filtering - that's what they're for. However, there are nuances here, I'll give you that. Like asking for the contents of a specific (empty) folder should not generate an error. Or asking for the "contents" of a specific (empty) file should not generate an error either.
rkeithhill commentedon Aug 22, 2018
Just because a command writes non-terminating errors doesn't mean it can't also throw terminating errors. A connectivity problem should result in a terminating error since there's no way the command can proceed.
SQLDBAWithABeard commentedon Aug 22, 2018
I can see that there are strong views for this to continue as originally specified but now I have access to a proper keyboard I will respond again.
This is the conundrum
If
Get-ChildItem EmptyFolder
Get-Module ModuleThatIsNotLoaded
should not return an error when there is nothing there
why should
Get-Command NoneExisitngCommand
return an error when there is no command of that name?
I have asked for this particular command and I have received an error rather than either
a, Here is precisely what you asked for - nothing
b, A more useful message to the user than a full error message
I disagree that this should be an error. I also find that it confuses newcomers. An error and a sea of red text means something is wrong and in this case nothing is wrong, it just doesn't exist.
Personally, I want it to return nothing because there is nothing to be returned. I would be happy with a warning but I see it as a direct question that should be return in a pedantic manner.
"Give me all of the Printers named foo please"
"Here are all of the printers named foo "

Funnily enough 5 minutes afer writing this I find another example that maybe also explains why I see it his way. This is what I get with the virtualmachinemanager module right now too.
Give me all of the Virtual Machines named $Vmname
(There aren't any - we are cleaning up a system of old data prior to upgrade)
Which makes my coding easier and training the users easier also ;-)
It makes it easier for users at the command line and it makes it easier for error handling too as Joel mentions above more eloquently than I can.
Thats my opinion
Jaykul commentedon Aug 22, 2018
@rkeithhill but you've ignored my argument in favor of picking apart the op examples. let's set all of that aside. Read my first reply, and explain to me how your logic applies to
Get-AzureKeyVaultSecret(after that, we can talk about all these other examples from a point of understanding each other, rather than just defending the current behavior).However, this comment seems like a HUGE misunderstanding, which in my opinion is the root cause of your point of view (and everyone who thinks these should error):
That's simply not reasonable. Take this sample command:
Are you saying that the user should just learn to ignore and live with the huge block of red from
Write-Error, or do you have a magic incantation whereby they can suppress it without suppressing the exception?rkeithhill commentedon Aug 22, 2018
Yup:
Or if you prefer:
@SQLDBAWithABeard then you should be disappointed in a lot of PowerShell
Get-commands: Get-Variable, Get-Process, Get-PSDrive, Get-PSRepository, Get-PackageSource, Get-PackageProvider, Get-DscResource, etc, etc, etc.RamblingCookieMonster commentedon Aug 22, 2018
I'm on board with what @Jaykul wrote up top. Tweet-sized:
The existing commands that follow the error-if-nothing-found convention are painful to deal with.
I don't understand why this is even up for debate. Do folks seriously want to create a common convention forcing everyone who writes PowerShell to handle multiple error types (which differ for each command, generally) for something that should (and often is, currently) as simple as testing for presence of a value? I realize some folks here are very experienced, but this seems like a bad idea that would affect the usability and desirability of the language for a large swath of folks, including myself.
rkeithhill commentedon Aug 22, 2018
I wonder if it is just the "sea of red" that so many folks have an aversion to that they're willing to not have commands error just to avoid it. I can certainly sympathize. We've tried in the past to argue for more succinct error msgs. I would love to see something like this:
What I don't like about that is that the $error collection is a stack and that error index above of
0is not stable. I'd like to see something more like this:where
8c1c74auniquely identifies the error record and can be used at any time up until that error record is "aged" out of the $error collection. That would look like:Also, with Get-Error, I'd like to see a
-Verboseparameter where I could get extended error details - much like the Resolve-Error (in PSCX) command provides:rkeithhill commentedon Aug 22, 2018
Yup. Although the "forcing everyone" bit sounds ominous. Did you see that list I posted above? You already have to do this with many
Get-*commands. Are you suggesting we should change those and incur breaking changes?Also folks seem to be only considering the scripting case and not the interactive CLI case. I happen to believe that most folks using a shell expect
Get-Item xyzzyto error - just not with a sea of red text. :-) It's been that way on Bash for decades, ditto for CMD.RamblingCookieMonster commentedon Aug 22, 2018
@rkeithhill or others who are in the
it should error when you request a specific item and that item is not found- can you spell out a value proposition here? I'm struggling to see one.bash does thisorsome-random-commanddoes this is not really a strong value here, IMHO, when this convention adds serious overheadrkeithhill commentedon Aug 22, 2018
Given that the system temp dir is
C:\Windows\Temp(and you are running elevated), what do you expect this to return:If this command were to return nothing, I would assume the directory is empty and not that it actually doesn't exist. That's not a good user experience.
SQLDBAWithABeard commentedon Aug 22, 2018
Yes - when considering this subject.
Although I can work around it when coding or when at the command line I can read it. I have to explain it to many people who are intimidated by the sea of red. I always want PowerShell to be as easy as possible for all people
If there is a chance to influence the choice, my choice is for no error if nothing to return
I think this is a poor example @rkeithhill GCI Folderthatdoesntexist is asking for the contents of a folder that doesnt exist so that should give some output
Get-Printer Doesntexist
Get-AzureRmVM -Name NotThere -ResourceGroup $RG
Should not error IMHO
rkeithhill commentedon Aug 22, 2018
This command can be easily made to behave the way you want:
BTW I think you guys are tilting at windmills here. On my Windows 10 1803 system in an elevated Windows PowerShell (more commands built-in), I count the following number of
getcommands:Of those 41, 29 of them error when the specified item is not found:
That's 71% of the built-in
Getcommands that do error when the specified item is not found. So even if you don't think the PowerShell Committee is right on this (and yeah, they do have a few years experience), I don't see them changing over to "not finding the specified item should not (non-term) error". That said, I do get @Jaykul perf argument for REST calls. But again, I think for new REST/remote commands like this, you just specify*to tell the command to not write a non-term error if the wildcard specifier results in no output.Update: the above results are highly dependent on what modules you have loaded. And it also only checks Get commands with a
Nameparameter. I tried this again with the just following modules loaded:And got 41/43 errored which is 95% that error. I'm sure the % will vary depending on the modules you have loaded.
SQLDBAWithABeard commentedon Aug 22, 2018
I know that it can. But I am not just speaking for me but for the people who read all the blog posts where this isn't mentioned for all of the commands they use who are confused or have extra work to do when there is an error. Lets make it easier for people
From the original post
If it was green field this would be my view. In the beginning, it was a different view and now the choice has been suggested to have a different view also. I am ok with that, if that is the way the majority want it.
I am not doubting all the years of experience that PowerShell committee have but I would say that there are folk commenting here and elsewhere with plenty of years experience as well and their opinion is welcomed as well
Also - can I mention my Warning suggestion again ? ;-)
RamblingCookieMonster commentedon Aug 22, 2018
something*looks innocuous enough. Using it can be dangerous. How many folks do you think will consider all the implications of a wildcard?This is the same deal with why we tell people to never, ever use ambiguous parameter names. What if
somethingelseis a thing you shouldn't be matching?You can justis a tempting refrain, but most alternatives I've seen here:rkeithhill commentedon Aug 22, 2018
Fair point. I suppose this would be less than satisfying:
Get-Something somethin[g]? :-) I guess there's no getting around some parameters inherently acting as filters.ergo3114 commentedon Aug 22, 2018
My expectation and joy of powershell is that Powershell will only error when something is a problem. Powershell has a precedence of great use of errors that help lead scripters to an actionable solution. Not being able to find something does not provide an actionable solution. Null data is not an issue it gives you just as much information about the output as actual data. Embrace null data.
MikeyBronowski commentedon Aug 23, 2018
Hi all. I am new PS user, with not much of experience of writing PS code.
I've read the thread and I can agree with people saying: I looked for something, that something does not exists, do not return anything.
It seems more natural to me when you go to a store looking for a thing and it's not there (because it's not there, or you have wrong name of the thing). The result would be : not found, rather than error.
Sometimes lack of any message can be confusing as may indicate some other problem.
When we apply analogy to search/not-found there is usually something like:
"not found", "not matching criteria", "0 results"
But in many cases it would be Information or Warning, not an Error.
Initially I might want to see the message, rather then nothing, but it might change when I have more experience with PS.
That's from the user perspective. Hope you find it helpful.
essentialexch commentedon Aug 24, 2018
Because more cmdlets don't follow the (good, IMO) example of Get-Command, this has become my scripting pattern:
Every comment line requires a different set of actions. Don't you think it's a bit ridiculous?
KevinMarquette commentedon Aug 25, 2018
I tend to call almost every command with either
-ErrorAction Stopor-ErrorAction Ignore. I either care about the error and want to do something when it happens, or I don't care at all because all it really means is that I'm not getting the data that I want and can't do anything about it.Any time I call a cmdlet that gets something, I have to check to make sure I got a value before continuing anyway. I kind of prefer to not return values over creating errors. I like to see errors as something unexpected. I expect that a get command will either get me something or it will not.
If we are talking green field here, I would require a
Test-command for everyGet-command that returns an error for no results. I want to be able to avoid errors, not suppress them or be required to handle them. If aTest-command does not make sense in the context of the command, then it does not make sense for theGet-command to generate errors for no results.I am OK with
GCIgiving me an error on a missing folder because I can test for it. Only I can decide if a missing folder is an expected or unexpected situation.joeyaiello commentedon Sep 5, 2018
Random collection of thoughts:
TimCurwick commentedon Sep 25, 2018
Joey,
Re you're being "open to hearing about more scenarios where non-terminating errors are...painful...."
At my level, much of my code is within try/catch blocks with ErrorActionPreference set to Stop, so non-terminating errors don't exist. Adding complexity to the error handling to handle "expected" errors different from actual errors is painful. It is much easier to distinguish between an error and a null result if one of them is an error and the other is a null result, instead of them being two different types of errors, terminating or not.
And at the level of the junior scripters that make up the bulks of the community, any unnecessary complexity is painful, slows adoption, and steepens the learning curve. It should be possible to add complexity to do complex things, but default behavior should make it simple to do simple things.
Jaykul commentedon Sep 25, 2018
@joeyaiello non-terminating errors are one of the most painful things in PowerShell, because literally at any time a caller of my code may change the rules by just calling my function with
-ErrorAction Stopand suddenly they all turn into terminating errors ...