I am trying to get my head around exceptions, and implement exception handling that ultimately gets logged, since my code runs as a remote job and reviewing a txt log is the best means of reviewing results. Currently I have an issue where "unexpected" exceptions only show up in the console, so my focus right now is dealing with that.

So... here I have a first pass at trying to catch an unexpected exception and provide output that shows me script name and line, the exception message, and the exception type so I can potentially go back and add "expected" exception handling by specific type, and log those slightly differently.

class PxUnexpectedException : Exception {
    #PxUnexpectedException() {}
    PxUnexpectedException([string] $message) : base($message) {}
    #PxUnexpectedException([string] $message, [Exception] $inner) : base($message, $inner) {}

    static [array] ReviseTrace ([string]$path, [array]$trace) {
        $scriptPath = ", $(Split-Path $path -parent)\"
        $revisedTrace = $trace -replace [Regex]::Escape($scriptPath), ' in '
        return $revisedTrace

function Test ($path) {
    try {
        Test-Path $path -errorAction:stop > $null
    } catch {
        # Standard Px error trap
        $trace = [PxUnexpectedException]::ReviseTrace($_.InvocationInfo.ScriptName, $_.ScriptStackTrace)
        throw [PxUnexpectedException] "[$($_.Exception.GetType().fullname)] $($_.Exception.Message)`n$trace"

function ConvertException ([Exception]$exception) {
    foreach ($line in ($exception.Message -split "`n")) {
        Write-Host "$line" -ForegroundColor:red

$path = '\\Server\InvalidFolder|'
try {
    Test $path
} catch [PxUnexpectedException] {
    ConvertException $_.Exception

My issue at this point is all the work needed to get a good message for throw [PxUnexpectedException]. I will have this same two lines (the $trace = and the throw) perhaps hundreds of times, and it feels like I SHOULD be able to instantiate my own exception but pass the entire error item to my constructor. Something like throw [PxUnexpectedException] $_ and handle creating the message within the constructor.

Am I really getting this all wrong? Or is duplication of code just the way this will have to be done? Also, in the .NET examples I have adapted my class from, all three constructors are there. But it seems to me that, assuming this IS the only way to build the message, the only constructor I will ever need is the one that takes the single $message argument, so simplification is best hear. Am I missing something and not having all three constructors is really going to come back to bite me?

  • \$\begingroup\$ Unable to find type [PxExpectedException]. \$\endgroup\$
    – JosefZ
    Commented Mar 27, 2020 at 10:51
  • \$\begingroup\$ @JosefZ Typo. The type should be [PxUnexpectedException] in all cases. Revised the OP. \$\endgroup\$ Commented Mar 27, 2020 at 13:15


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.