Reputation: 88
I'm working with a wrapper script that calls a function which queries some databases inside specified servers and inserts metadata to a specific database on a separate server. I use the $error.count variable to determine if the script was successful or not. I anticipate some permission/extraction errors to happen and want these to be caught and ignored (no increase in the $error.count variable but having a warning written in the job log). I can confirm one permission error is happening and is being properly caught. The $error.count variable is not increased but a warning is printed from the catch showing the database that could not be accessed.
My problem occurs after the extraction/insertion function is finished running. Immediately after this function returns to the wrapper script, I have the $error.count variable print again. This time, it returns a 1 as if the error previously caught cascades into the wrapper script. As I mentioned previously, I do not want this to be included in the error count. I'm not sure how or why the $error.count is increased from this function.
Should I use a different variable to determine if the script "failed" or not? Is there some underlying reason why the $error.count would increase outside of the function that has the error while not increasing after the error is caught? Any guidance on this issue would be appreciated.
Code for reference: Wrapper function:
$errorCount = $error.count
Write-Warning ("$errorCount Before function")
Extraction/Insertion_Function -serverList $serverList -insertionDB $insertionDB -ErrorAction SilentlyContinue
$errorCount = $error.count
Write-Warning ("$errorCount After function")
} catch {
Write-Error "Error caught by wrapper: $_"
}
Extraction/Insertion_Function:
ForEach ($db in $dbList) {
Write-Warning "$errorCount database
.
.
.
try {
$totalProperties = Get-ServerDBMetadata -DBConnectionString ($connStr) -DatabaseName $dbName -EA SilentlyContinue
} catch {
Write-Warning "Unable to extract metadata from $dbname in $server"
}
}
I then have the error count printing out inside the loop that extracts/inserts the metadata from each database to the insertion database, as well as in the loop for each server that contains the databases:
WARNING: 0 Before function
WARNING: 0 database
.
.
.
WARNING: 0 database
WARNING: Unable to extract metadata from *database* in *server*
WARNING: 0 database
.
.
.
WARNING: 0 database
**WARNING: 1 After function**
The error (permission issue) is caught inside the function but cascades to my wrapper script. I want this particular error to be ignored while NOT ignoring other, more serious errors (like being unable to connect to the server I'm inserting the metadata into) so placing -EA Ignore on the driver function inside the wrapper script is out of the question.
Upvotes: 2
Views: 520
Reputation: 2935
Your primary problem with the try-catch not catching the error (even though you don't supply all of the code) is that your cmdlet explicitly calls -ErrorAction SilentlyContinue
. Try/Catch blocks REQUIRE the use of terminating errors so in the case of your function/cmdlet, you need to change to -ErrorAction Stop
for try/catch to appropriately handle an error from that function/cmdlet.
This needs to be updated for any other function/cmdlet in the code we can't see.
Edit described in comments below:
$n = New-Object PSObject -property @{
'Test1' = ''
'Test2' = ''
'Test3' = ''
}
try {
get-process someprocess -ErrorAction Stop
$n.Test1 = $true
} catch {
$n.Test1 = $false
}
try {
Get-WmiObject win32_computersystem -ErrorAction Stop
$n.Test2 = $true
} catch {
$n.Test2 = $false
}
try {
Get-Content somefile.ext -ErrorAction Stop
$n.Test3 = $true
} catch {
$n.Test3 = $false
}
if ($n.Test1 -and $n.Test2 -and $n.Test3) {
## All procedures completed successfully -- do something magical
} else {
## At least one test procedure failed.
}
Upvotes: 2
Reputation: 10019
Replace SilentlyContinue
with Ignore
to ignore the error and not have it increase the count.
Extraction/Insertion_Function -serverList $serverList -insertionDB $insertionDB -ErrorAction Ignore
To catch it inside the function, use -ErrorAction Stop
as in thepip3r's answer as try/catch statements only catch terminating errors.
Upvotes: 2
Reputation: 23830
Logging the remaining errors since the last log:
While ($Global:ErrorCount -lt $Error.Count) {
$Err = $Error[$Error.Count - ++$Global:ErrorCount]
$ErrLine = "Error at $($Err.InvocationInfo.ScriptLineNumber),$($Err.InvocationInfo.OffsetInLine): $Err"
Write-Host $ErrLine -ForegroundColor Red # Log this
}
Upvotes: 1