2

assume I've got a Function Add-Values, how to avoid an ugly error-message, when one gives a string and not an integer for the paramters?

Function Add-Values
{
    param(
    [parameter(mandatory=$true)][int]$val1,
    [parameter(mandatory=$true)][int]$val2
    )

    $val1 + $val2
}

Thank you for the help

4
  • what do you mean by "ugly error-message" ? (can you add an example) Commented Nov 29, 2019 at 12:46
  • when I call the Function like this: Add-Values "abc" 7 I get an error: Add-Values : Cannot process argument transformation on parameter 'val1'. Cannot convert value "ab" to type "System.Int32". Error: "Input string was not in a correct format." At line:1 char:12 + Add-Values "ab" 7 + ~~~~ + CategoryInfo : InvalidData: (:) [Add-Values], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Add-Values. Actually I'd like to prevent such an error message. Commented Nov 29, 2019 at 12:48
  • So what should it do with "abc" and 7, instead of throwing an error? Commented Nov 29, 2019 at 12:49
  • simply saying: "wrong input" for example? Commented Nov 29, 2019 at 12:52

2 Answers 2

3

Janne Tuukkanen's helpful answer provides an effective solution.

Taking a step back:

It's understandable to want to avoid the notoriously noisy, multi-line default error formatting in Windows PowerShell and PowerShell [Core] 6.x versions, which can be confusing to end users.

Two - suboptimal - options are:

  • Use $host.UI.WriteErrorLine($errMsg), which prints just the content of $errMsg in red, without any additional information.

  • Another option is to use Write-Warning $errMsg, which prints the message in yellow, but prefixes it with WARNING:.

In general, though, it is best not to bypass the usual error reporting features (for consistency and to support further programmatic processing), which PowerShell [Core] 7+ can help with:

PowerShell [Core] 7+ now defaults to concise error formatting, via the ConciseView view that was introduced in 7.0:

With preference variable $ErrorView set to the new default, ConciseView, your command would fail as follows if given a non-integer (prints on a single line, in red; spread across multiple lines here for readability):

Add-Values: Cannot process argument transformation on parameter 'val1'. 
Cannot convert value "abc" to type "System.Int32". 
Error: "Input string was not in a correct format."

Screen shot (custom background color):

enter image description here

While certainly an improvement over the old formatting, it is still somewhat wordy.

However, you can perform custom validation on parameters via the [ValidateScript()] attribute, which in PowerShell v6+ also supports an ErrorMessage property, so you could do the following:

Function Add-Values
{
  param(
    [ValidateScript({ ($_ -as [int]) -is [int] }, ErrorMessage='Please pass an integer.')]
    [Parameter(Mandatory)]
    $val1
    ,
    [ValidateScript({ ($_ -as [int]) -is [int] }, ErrorMessage='Please pass an integer.')]
    [Parameter(Mandatory)]
    $val2
  )

  $val1 + $val2
}

Note:

  • The [ValidateScript()] attribute accepts a script block inside of which the value passed by the user is reflected in the automatic $_ variable. The script block must output a Boolean that indicates whether the value is valid - (effectively) $true) - or not - (effectively) $false.

  • Only script-block literals ({ ... }) and (non-expandable) string literals are supported inside [ValidateScript()], so the values must be repeated for the two parameters.

  • ($_ -as [int]) -is [int] uses the -as operator to see if the given parameter value ($_) is already an [int] or can be converted to one, and returns an [int] instance if so, and $null otherwise. -is [int] then tests if the -as operation indeed returned an integer or not.

With invalid arguments - e.g., Add-Values abc 2 - you'll then get something like the following:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

2

Just leave the type undefined in the parameter declaration, and check them in the function code:

function Foo {
    param(
        [parameter(Mandatory)]$a,
        [parameter(Mandatory)]$b
    )

    if($a -is [int] -and $b -is [int]) {
        return $a + $b
    }

    Write-Output "Bad parameters"
}

1 Comment

I appreciate it, Janne (+1). Please also consider replacing Write-Output with something like $host.ui.WriteErrorLine('Bad parameters') (Write-Error is conceptually appropriate, but avoiding the "noise" it generates is what prompted the question to begin with).

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.