# Error Handling

## ERR-01 Use -ErrorAction Stop when calling cmdlets

When trapping an error, try to use -ErrorAction Stop on cmdlets to generate terminating, trappable exceptions.

## ERR-02 Use $ErrorActionPreference = 'Stop' or 'Continue' when calling non-cmdlets

When executing something other than a cmdlet, set $ErrorActionPreference = 'Stop' before executing, and re-set to Continue afterwards. If you're concerned about using -ErrorAction because it will bail on the entire pipeline, then you've probably over-constructed the pipeline. Consider using a more scripting-construct-style approach, because those approaches are inherently better for automated error handling.

Ideally, whatever command or code you think might bomb should be dealing with one thing: querying one computer, deleting one file, updating one user. That way, if an error occurs, you can handle it and then get on with the next thing.

## ERR-03 Avoid using flags to handle errors

Try to avoid setting flags:

```
try {
    $continue = $true
    Do-Something -ErrorAction Stop
} catch {
    $continue = $false
}

if ($continue) {
    Do-This
    Set-That
    Get-Those
}
```

Instead, put the entire "transaction" into the Try block:

```
try {
    Do-Something -ErrorAction Stop
    Do-This
    Set-That
    Get-Those
} catch {
    Handle-Error
}
```

It's a lot easier to follow the logic.

## ERR-04 Avoid using $?

When you need to examine the error that occurred, try to avoid using $?. It actually doesn't mean an error did or did not occur; it's reporting whether or not the last-run command considered itself to have completed successfully. You get no details on what happened.

## ERR-05 Avoid testing for a null variable as an error condition

Also try to avoid testing for a null variable as an error condition:

```
$user = Get-ADUser -Identity DonJ

if ($user) {
    $user | Do-Something
} else {
    Write-Warning "Could not get user $user"
}
```

There are times and technologies where that's the only approach that will work, especially if the command you're running won't produce a terminating, trappable exception. But it's a logically contorted approach, and it can make debugging trickier.

## ERR-06 Copy $Error\[0] to your own variable

Within a `catch` block, `$_` will contain the last error that occurred, as will `$Error[0]`. Use either - but immediately copy them into your own variable, as executing additional commands can cause `$_` to get "hijacked" or `$Error[0]` to contain a different error.

It isn't necessary to clear `$Error` in most cases. `$Error[0]` will be the last error, and PowerShell will maintain the rest of the `$Error` collection automatically.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://poshcode.gitbook.io/powershell-practice-and-style/best-practices/error-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
