{"id":73321,"date":"2015-09-16T00:01:00","date_gmt":"2015-09-16T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/09\/16\/understanding-non-terminating-errors-in-powershell\/"},"modified":"2019-02-18T09:35:13","modified_gmt":"2019-02-18T16:35:13","slug":"understanding-non-terminating-errors-in-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/understanding-non-terminating-errors-in-powershell\/","title":{"rendered":"Understanding Non-Terminating Errors in PowerShell"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Ed Wilson, Microsoft Scripting Guy, talks about understanding non-terminating errors in Windows PowerShell.<\/span><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;Hey, Scripting Guy! Yesterday in <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/error-handling-two-types-of-errors\/\" target=\"_blank\">Error Handling: Two Types of Errors<\/a>, you were talking about terminating errors and how you can use <b>Try<\/b>\/<b>Catch<\/b>\/<b>Finally<\/b> with those, but you did not really say what a non-terminating error is. Can you talk about that for a little bit please?<\/p>\n<p>&mdash;SK<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello SK,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sitting here sipping a cup of English Breakfast tea with a cinnamon stick in it, and munching on a piece of baklava. You see, we just celebrated my birthday weekend, and instead of baking a cake, the Scripting Wife headed out to my favorite Egyptian Caf&eacute;, and picked up some homemade baklava.<\/p>\n<p>When I was in Egypt, I never had baklava. I always thought it was more of a Greek thing. But hey, it works. This little caf&eacute; does an excellent job making baklava, and as it turns out, it is an amazing birthday cake&mdash;just a little hard on the candles. It is about a perfect combination with English Breakfast tea. It&#039;s a little sticky, but lots of things in life are sticky&mdash;like trying to figure out the difference between a terminating and a non-terminating error in Windows PowerShell.<\/p>\n<h2>Try\/Catch\/Finally&hellip;doesn&rsquo;t work<\/h2>\n<p>So, I write some code and try to catch an error, but it doesn&#039;t work. What&rsquo;s up with that? Well, if <b>Try<\/b>\/<b>Catch<\/b>\/<b>Finally<\/b> does not work, there are a few potential problems. The first is that the <b>Catch<\/b> may be trying to catch something that does not actually happen. For example, if I try to catch an error related to a process that does not exist, but that process does in fact exist, the <b>Catch<\/b> will not trigger.<\/p>\n<p>So, if I want to catch all errors that occur, I will catch a [System.Exception] because that is the root of all errors. Here is the <b>Catch<\/b> block I use:<\/p>\n<p style=\"margin-left:30px\">Catch [System.Exception] {&quot;Caught the exception&quot;}<\/p>\n<p>The next thing to realize is that if I try something, and it does not generate a terminating error, it will not move into the <b>Catch<\/b> block anyway. This is because the default for <b>$ErrorActionPreference<\/b> (what Windows PowerShell will do when an error arises) is to continue to the next command.<\/p>\n<p>In reality, this means that if an error occurs and Windows PowerShell can recover from it, it will attempt to execute the next command. But it will let you know the error occurred by displaying the error to the console.<\/p>\n<p>If I want to see what Windows PowerShell will do when a non-terminating error arises, I look at the value of the <b>$ErrorActionPreference<\/b> variable, for example:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $ErrorActionPreference<\/p>\n<p style=\"margin-left:30px\">Continue<\/p>\n<p>Here is a <b>Try<\/b> statement that tries to do something. It will get a directory list of a missing folder. But because that folder is missing, it will generate an error. Here is the <b>Try<\/b>\/<b>Catch<\/b>\/<b>Finally<\/b> block:<\/p>\n<p style=\"margin-left:30px\">Try {dir c:\\missingFolder }<\/p>\n<p style=\"margin-left:30px\">Catch [System.Exception] {&quot;Caught the exception&quot;}<\/p>\n<p style=\"margin-left:30px\">Finally {$error.Clear() ; &quot;errors cleared&quot;}<\/p>\n<p>When I run the code, and error message appears in the Windows PowerShell console output. It also says that the errors are cleared, which is command that is written into the <b>Finally<\/b> block. But the System.Exception error was not caught because the <b>&ldquo;Caught the Exception&rdquo;<\/b> string was not emitted. This output is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-16-15-01.jpg\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-16-15-01.jpg\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>If I look at the <b>$Error<\/b> variable, I see that there are, in fact, no errors there. So the <b>$Error.Clear()<\/b> command did take place. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $Error<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $Error.Count<\/p>\n<p style=\"margin-left:30px\">0<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt;&nbsp;<\/p>\n<p>But, why did the <b>Directory not found<\/b> error message appear? Because the <b>ErrorAction Preference<\/b> is set to <b>Continue<\/b>:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $ErrorActionPreference<\/p>\n<p style=\"margin-left:30px\">Continue<\/p>\n<p>One way to force the error to stop Windows PowerShell, instead of permitting it to continue to the next line, is to change the <b>ErrorAction<\/b> preference from <b>Continue<\/b> to <b>Stop<\/b>. I can do this at the cmdlet level. I use the <b>&ndash;ErrorAction<\/b> automatic parameter from the <b>Get-ChildItem<\/b> cmdlet (<b>Dir<\/b> is an alias), and I change it to <b>Stop<\/b>. This causes the error to terminate the Windows PowerShell execution and forces it to the <b>Catch<\/b> block. Here is the change:<\/p>\n<p style=\"margin-left:30px\">Try {dir c:\\missingFolder -ErrorAction Stop}<\/p>\n<p style=\"margin-left:30px\">Catch [System.Exception] {&quot;Caught the exception&quot;}<\/p>\n<p style=\"margin-left:30px\">Finally {$error.Clear() ; &quot;errors cleared&quot;}<\/p>\n<p>Here is the output:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-16-15-02.jpg\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-16-15-02.jpg\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> This entire error issue could have been avoided by using tab completion in the first place. This is because C:\\missingfolder does not exist, and if I had used tab complete for the directory, I would have seen that it did not appear. By &ldquo;doing the right thing&rdquo; in the first place, I could have avoided the complexity of structured error handling&mdash;at least for this script.<\/p>\n<p>SK, that is all there is to understanding non-terminating errors. Error Handling Week will continue tomorrow when I will talk about forcing non-terminating errors to terminate.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, talks about understanding non-terminating errors in Windows PowerShell. &nbsp;Hey, Scripting Guy! Yesterday in Error Handling: Two Types of Errors, you were talking about terminating errors and how you can use Try\/Catch\/Finally with those, but you did not really say what a non-terminating error is. Can you talk about that [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[68,3,4,45],"class_list":["post-73321","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-error-handling","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, talks about understanding non-terminating errors in Windows PowerShell. &nbsp;Hey, Scripting Guy! Yesterday in Error Handling: Two Types of Errors, you were talking about terminating errors and how you can use Try\/Catch\/Finally with those, but you did not really say what a non-terminating error is. Can you talk about that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/73321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=73321"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/73321\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=73321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=73321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=73321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}