Write-Error, $Error, and Users
Write-Error is useful, but the output is intimidating for new users. You want them to see a nice message, but they get a wall of red text including a stack dump.
Here’s a way to output it as a warning, but populate $Error as well.
function Out-Error
{
param (
[String]$Message = "No error message.",
[System.Management.Automation.ErrorCategory]$Category = 'NotSpecified',
[System.Management.Automation.ActionPreference]$ErrorAction = $Script:ErrorAction
);
$message = "($((Get-Variable -Scope 1 -Name MyInvocation -ValueOnly).MyCommand.Name)) $message";
Write-Warning -Message $message;
Write-Error -ErrorAction SilentlyContinue -Message $message -Category $category;
if ($ErrorAction -notmatch ‘Continue$’)
{
break function;
}
}
Here's the function in a basic script outline:
param (
[System.Management.Automation.ActionPreference]$ErrorAction = $(Get-Variable -Scope 1 -Name ErrorActionPreference -ValueOnly),
[switch]$AppendError
);
Begin
{
#region functions
function Out-Error
{
param (
[String]$Message = "No error message.",
[System.Management.Automation.ErrorCategory]$Category = 'NotSpecified',
[System.Management.Automation.ActionPreference]$ErrorAction = $Script:ErrorAction
);
$message = "($((Get-Variable -Scope 1 -Name MyInvocation -ValueOnly).MyCommand.Name)) $message";
Write-Warning -Message $message;
Write-Error -ErrorAction SilentlyContinue -Message $message -Category $category;
if ($ErrorAction -notmatch ‘Continue$’)
{
break function;
}
}
function Test-OutError
{
param (
[string]$bar,
[switch]$foo
);
# do stuff
Out-Error -Message 'we failed to do stuff' -Category ObjectNotFound;
# do more stuff
Out-Error -Message "-Foo $foo we failed to do more stuff with -Bar '$bar'." -Category ObjectNotFound;
}
function Test-OutError2
{
param (
[string]$bar,
[switch]$foo
);
# do stuff
Out-Error -Message 'we failed to do stuff' -Category ObjectNotFound -ErrorAction Stop;
# do more stuff
Out-Error -Message 'we failed to do more stuff' -Category ObjectNotFound;
}
#endregion
#region initialization
if (!$AppendError)
{
$Error.Clear();
}
#endregion
}
Process
{
# do stuff
Test-OutError -bar baz;
Test-OutError2 -foo -bar baz;
}
End
{
# do stuff on success
# do stuff unconditionally
:function foreach ($_ in 1)
{
$Error | Export-Clixml -Path "$home\Error.Clixml";
}
}