iainbrighton / PScribo

PowerShell documentation framework
MIT License
230 stars 35 forks source link

Error: "Index was outside the bounds of the array" when using 'Table' command with 'ColumnWidths' parameter & Word format #118

Closed tpcarman closed 1 year ago

tpcarman commented 2 years ago

The following code will cause the error Index was outside the bounds of the array when exporting a document in Word format. The error occurs when using the ColumnWidths parameter.

Exporting to HTML and Text formats does not generate the error.

This issue has been tested and confirmed using PScribo versions 0.9.1 & 0.10.0.

[CmdletBinding()]
param (
    [System.String[]] $Format = 'Word',
    [System.String] $Path = "$env:USERPROFILE\documents",
    [System.Management.Automation.SwitchParameter] $PassThru
)

Import-Module PScribo -Force -Verbose:$false

$example17 = Document -Name 'PScribo Example 17' {

    <#
        To create a multi-row table from hashtables, simply create a collection/
        array of ordered hashtables.

        NOTE: You must ensure that the hashtable keys are the same on all hashtables
              in the collection/array as only the first object is enumerated.

        The following example creates an table with a three rows from an array of
        ordered hashtables.
    #>
    $hashtableArray = @(
        [Ordered] @{ 'Column 1' = 'Some random text'; 'Column2' = 345; 'Custom Property' = $true; }
        [Ordered] @{ 'Column 1' = 'Random some text'; 'Column2' = 16; 'Custom Property' = $false; }
        [Ordered] @{ 'Column 1' = 'Text random some'; 'Column2' = 1GB; 'Custom Property' = $true; }
    )
    Table -Hashtable $hashtableArray -List -Key 'Column 1' -ColumnWidths 20, 40, 40
}
$example17 | Export-Document -Path $Path -Format $Format -PassThru:$PassThru
Index was outside the bounds of the array.
At line:95 char:25
+ ...             $newPScriboFormattedTableRowValueCellParams['Width'] = $T ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Index was outside the bounds of the array.
At line:95 char:25
+ ...             $newPScriboFormattedTableRowValueCellParams['Width'] = $T ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Index was outside the bounds of the array.
At line:133 char:25
+ ...         if (($null -ne $Table.ColumnWidths) -and ($null -ne $Table.Co ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Index was outside the bounds of the array.
At line:133 char:25
+ ...         if (($null -ne $Table.ColumnWidths) -and ($null -ne $Table.Co ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Index was outside the bounds of the array.
At line:133 char:25
+ ...         if (($null -ne $Table.ColumnWidths) -and ($null -ne $Table.Co ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException
carceneaux commented 1 year ago

I can confirm this behavior. It also exists with the HTML format:

Scripts> .\Test.ps1
Index was outside the bounds of the array.
At line:95 char:25
+ ...             $newPScriboFormattedTableRowValueCellParams['Width'] = $T ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Index was outside the bounds of the array.
At line:95 char:25
+ ...             $newPScriboFormattedTableRowValueCellParams['Width'] = $T ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
    + FullyQualifiedErrorId : System.IndexOutOfRangeException

Some more digging and this is the line of code dropping the error. As you'd expect both Word & Html plugins leverage this function.

I'll debug some more to determine the root cause.

carceneaux commented 1 year ago

@tpcarman Please check out #125 as I've added logic to avoid this error and generate a warning:

CleanShot 2022-12-20 at 11 24 41

The root cause of this issue was the ColumnWidths count not matching the number of columns in the table.

For example, here's the code you shared:

Table -Hashtable $hashtableArray -List -Key 'Column 1' -ColumnWidths 20, 40, 40

Here we see 3 ColumnWidths values (20, 40, 40). However, as this is a List with a Key specified, the Key adds an additional column so 4 ColumnWidths values are required. We can confirm this by removing the ColumnWidths altogether and we see:

CleanShot 2022-12-20 at 11 30 42

iainbrighton commented 1 year ago

As @carceneaux pointed out, you need to add an additional column width to the array to account for the additional column. I have an updated warning in some code waiting to be pushed (I think @carceneaux might also have addressed this in an outstanding PR).

tpcarman commented 1 year ago

Thanks @carceneaux and @iainbrighton for looking into this for me. Glad to see some improvements in the error handling will be added in future updates.