Greetings,
Recently, I’ve been working in PowerShell. Tintri has a great PowerShell Toolkit, but unfortunately some APIs cannot be invoked via the Toolkit. So to invoke APIs that are not in the Toolkit, you can use Microsoft’s Invoke-RestMethod. In this blog, I’m only going to discuss exception handling.
Try {
$resp = Invoke-RestMethod -Uri $url -Method Delete -WebSession $session -ContentType $JSON_CONTENT
}
Catch {
# Obtain some information
$expMessage = $_.Exception.Message
$failedItem = $_.Exception.Source
$line = $_.InvocationInfo.ScriptLineNumber
# Check if there is a response.
if ($_.Exception.Response -eq $null) {
Write-Host "At $($line):`r`n$expMessage" -ForeGroundColor Red
}
else {
# Get the response body with more error detail.
$respStream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($respStream)
$respBody = $reader.ReadToEnd() | ConvertFrom-Json
$errorCode = $respBody.code
$errorMessage = $respBody.message
$causeDetails = $respBody.causeDetails
Write-Host "At line $($line):`r`n$expMessage`r`n$($errorCode): $errorMessage`n`r $causeDetails" -ForegroundColor Red
}
}
Take the example code above where we invoking a GET API. The variable $session is the session ID and $url is of course the API URL.
If there is an Invoke-RestMethod() error, the exception is thrown and the Catch block is executed. When a Tintri API error occurs Invoke-RestMethod does not return any data, and there is more information in the API response. See the Error Handling section in the API documentation where the error response is documented:
{"typeId":"com.tintri.api.rest.v310.dto.domain.beans.TintriError",
"code":"ERR-API-8001",
"message":"Failed to find requested resource of type VirtualMachine with id: 'xxxxddd'",
"causeDetails":"",
"title":"Resource not found"
}
So how do you get that error information in the response? Fortunately Chris Wahl shared some great information on his blog. As you can see, the first three bold lines in the second part of the Catch block is directly from Chris. The italicized part is what I added for Tintri errors.
The code now checks Exception.response; therefore, this Catch block can now handle both non-Tintri and Tintri errors. I changed Write-Error to Write-Host with a red foreground color for simpler output.
The response stream returns a string. To get the error code and the error message, the split function would need to be used twice within a loop; or just call ConvertFrom-JSON which which gives us a nice dictionary to easily pluck out errorCode, errorMessage, and causeDetails.
Until next time,
– Rick –