Change the originator of rethrown ErrorRecord

Howdy!

If I write the following Code which produce intentionally an Error the reported originator of the error is Get-Item not my Function named Get-MyFile in the Error message to the user.
This irritates the user because he has not called Get-Item.

Function Get-MyFile {

  param(
    [String[]]$Path
  )
  
  Try{
    Get-Item -Path $Path
  } Catch {
    Write-Error $_ 
  }
}


Get-MyFile -Path 'C:\DoesNotExist.txt'

How can i Change the Reported Cmdlet\Function Name inside the ErrorRecord to my Function Name, to Report it correctly to the user?

$Error[0].ScriptStackTrace

Reports correctly my function ‘Get-MyFile’ as the originator!

If I got you right - instead of writing the original error to the console in the catch block you should write an error message you create by yourself.

I’m not sure exactly what you are working towards. The Catch block in your code will ONLY work for terminating errors. The get-item error is not terminating, so your catch block is not working. If you want to verify you can debug and step through or print another message. i.e.

Function Get-MyFile {

  param(
    [String[]]$Path
  )
  
  Try{
    Get-Item -Path $Path
  } Catch {
    "Hello, is it me your looking for?"
  }
}


Get-MyFile -Path 'C:\DoesNotExist.txt'

If you want to catch the error and give a different response to the user using try, catch blocks, you can do it this way.

Function Get-MyFile {

  param(
    [String[]]$Path
  )
  
  Try{
    if (Test-Path -Path $Path) {Get-Item -Path $Path}
    else {throw}
  } Catch {
    "$Path does not exist"
  }
}

Get-MyFile -Path 'C:\DoesNotExist.txt'

You have two issues here.

One is using Write-Error. This is nice for short and simple stuff, but as you’ll see in a second, it doesn’t give a useful error either.

The other, more importantly, is that your Try/Catch isn’t being triggered. A Catch block only triggers on a terminating error, and the FileNotFound error you get here is non-terminating. So, step one of the fix:

Function Get-MyFile {

  param(
    [String[]]$Path
  )
  
  Try{
    Get-Item -Path $Path -ErrorAction Stop
  } Catch {
    Write-Error $_ 
  }
}


Get-MyFile -Path 'C:\DoesNotExist.txt'

Add -ErrorAction Stop to ensure that the error generated is given as terminating, triggering the catch block and letting you do what you want. If you try to call this version of the function, you’ll notice something interesting. It actually points the user back to the Write-Error cmdlet! This is very weird and unhelpful to most users, plus it often shows surrounding code lines, which might be confusing or at least undesirable.

So, two more changes. One is you need to apply the [CmdletBinding()] attribute. The other, you need to pull from $PSCmdlet methods to rethrow the error properly.

Function Get-MyFile {
  [CmdletBinding()]
  param(
    [String[]]$Path
  )
  
  Try{
    Get-Item -Path $Path
  } Catch {
    $PSCmdlet.WriteError($_)
  }
}


Get-MyFile -Path 'C:\DoesNotExist.txt'

And now when running the code you’ll see that instead of giving back the error saying that the Get-Item call failed, or that there was an error… on a write-error line… (obviously not helpful and just such a strange way of implementing it) – instead, it just points directly to the line where they called the function, and says “can’t find the path” – exactly what you want.

Thank you very much Joel

[Cmdletbinding()] + -ErrorAction ‘Stop’ + $PSCmdlet.WriteError($_) was the solution.

Function Get-MyFile {
  [CmdletBinding()]
  param(
    [String[]]$Path
  )
  
  Try{
      Get-Item -Path $Path -ErrorAction 'Stop'
  } Catch {
      $DebugPreference = 'Continue'
      Write-Debug "Greets from Catch block"
      $PSCmdlet.WriteError($_)
  }
}


Get-MyFile -Path 'C:\DoesNotExist.txt'