babalae/better-genshin-impact · error · InvalidOperationException

创建维度为 {dimensions} 的数组失败: {ex.Message}

Error message

创建维度为 {dimensions} 的数组失败: {ex.Message}

What it means

InvalidOperationException thrown by CustomHostFunctions.NewVarOfArr<T> at line 31, wrapping any exception raised while building a jagged array type via reflection. The method repeatedly calls Type.MakeArrayType() `dimensions` times, then reflects HostFunctions.newVar to expose it to ClearScript. Failures come from: negative dimensions (MakeArrayType accepts 0+), implausibly large dimensions exhausting type-system limits, T being a type ClearScript cannot marshal, or HostFunctions.newVar not being invokable on this instance. The original error is preserved in InnerException.

Source

Thrown at BetterGenshinImpact/Core/Script/Dependence/CustomHostFunctions.cs:31

    /// <param name="dimensions">数组维度</param>
    /// <returns>交错数组变量</returns>
    public object NewVarOfArr<T>(int dimensions)
    {
        try
        {
            Type arrayType = typeof(T);
            for (int i = 0; i < dimensions; i++)
            {
                arrayType = arrayType.MakeArrayType();
            }

            MethodInfo newVarMethod = typeof(HostFunctions).GetMethod(nameof(newVar))!;
            MethodInfo genericMethod = newVarMethod.MakeGenericMethod(arrayType);
            return genericMethod.Invoke(this, new object?[] { null })!;
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"创建维度为 {dimensions} 的数组失败: {ex.Message}", ex);
        }
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Validate dimensions: require 0 <= dimensions <= ~5 (a sane cap) before calling.
  2. Inspect `ex.InnerException` (and `InnerException.InnerException` for TargetInvocationException) to find the real cause — the outer message only restates it.
  3. Ensure NewVarOfArr is called on a HostFunctions instance attached to a live ScriptEngine.
  4. Confirm T is a host-exposed, marshalling-compatible type.

Example fix

// before (C#)
public object NewVarOfArr<T>(int dimensions)
{
    try
    {
        Type arrayType = typeof(T);
        for (int i = 0; i < dimensions; i++) arrayType = arrayType.MakeArrayType();
        MethodInfo genericMethod = typeof(HostFunctions).GetMethod(nameof(newVar))!.MakeGenericMethod(arrayType);
        return genericMethod.Invoke(this, new object?[] { null })!;
    }
    catch (Exception ex)
    {
        throw new InvalidOperationException($"创建维度为 {dimensions} 的数组失败: {ex.Message}", ex);
    }
}

// after (C#) — validate dimensions and unwrap the real error
public object NewVarOfArr<T>(int dimensions)
{
    if (dimensions < 0 || dimensions > 5)
        throw new ArgumentOutOfRangeException(nameof(dimensions), "dimensions must be between 0 and 5");
    try
    {
        Type arrayType = typeof(T);
        for (int i = 0; i < dimensions; i++) arrayType = arrayType.MakeArrayType();
        MethodInfo genericMethod = typeof(HostFunctions).GetMethod(nameof(newVar))!.MakeGenericMethod(arrayType);
        return genericMethod.Invoke(this, new object?[] { null })!;
    }
    catch (TargetInvocationException ex)
    {
        throw new InvalidOperationException($"创建维度为 {dimensions} 的数组失败: {ex.InnerException?.Message}", ex.InnerException ?? ex);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// C# — bound the dimensions argument
if (dimensions < 0 || dimensions > 5)
    throw new ArgumentOutOfRangeException(nameof(dimensions), "dimensions must be between 0 and 5");

Try / catch

try
{
    return hostFunc.NewVarOfArr<T>(dimensions);
}
catch (InvalidOperationException ex)
{
    // The real cause is in InnerException (often TargetInvocationException)
    var root = ex.InnerException is TargetInvocationException tie ? tie.InnerException : ex.InnerException;
    throw new InvalidOperationException($"NewVarOfArr failed for dim {dimensions}: {root?.Message}", root ?? ex);
}

Prevention

When it happens

Trigger: JS calls `hostFunc.NewVarOfArr(-1)` or `NewVarOfArr(1000)`. T resolves to a type the host cannot bind. The HostFunctions instance is in an invalid script context (e.g. used outside a ScriptEngine host).

Common situations: Script passes a user-controlled or computed dimensions value without bounds-checking. Recursive/nested generic array construction exceeding runtime limits. Type mismatch between JS expectation and the generic T inferred by ClearScript.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/0a6d9e0facbac3fb. Report an issue: GitHub.