babalae/better-genshin-impact · error · InvalidOperationException

实例 IPC 请求失败。

Error message

实例 IPC 请求失败。

What it means

Thrown by EnsureSuccessfulResponse as the fallback message when response.Success is not true (i.e., false or null) and both response.ErrorMessage and response.ErrorCode are null. The method checks Success == true for success; anything else throws InvalidOperationException. If the failure envelope was constructed without an error message or code (e.g., via new InstanceIpcEnvelope { Success = false }), this generic text is used.

Source

Thrown at BetterGenshinImpact/Service/Instance/InstanceService.cs:607

    {
        var application = Application.Current;
        if (application is null)
        {
            Environment.Exit(0);
            return;
        }

        _ = application.Dispatcher.BeginInvoke(new Action(application.Shutdown));
    }

    private static void EnsureSuccessfulResponse(InstanceIpcEnvelope response)
    {
        if (response.Success == true)
        {
            return;
        }

        throw new InvalidOperationException(
            response.ErrorMessage ?? response.ErrorCode ?? "实例 IPC 请求失败。");
    }

    private static async Task AwaitBackgroundTaskAsync(Task? task)
    {
        if (task is null)
        {
            return;
        }
        try
        {
            await task.ConfigureAwait(false);
        }
        catch (Exception exception) when (exception is IOException
                                          or OperationCanceledException
                                          or ObjectDisposedException)
        {
            // HostedService 停止期间的正常清理。

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Inspect the actual InstanceIpcEnvelope response object before the throw — log response.Success, response.ErrorCode, response.ErrorMessage, and response.Data to see what the peer actually sent.
  2. Ensure all remote handlers use InstanceIpcEnvelope.Failure(request, errorCode, errorMessage) so error details are always populated.
  3. Verify the JSON serialization settings (CamelCasePropertyNamesContractResolver, NullValueHandling.Ignore) are identical on both peers so ErrorCode/ErrorMessage are not dropped.
  4. If this occurs with a specific operation, trace the handler on the remote side to confirm it returns a descriptive failure.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    EnsureSuccessfulResponse(response);
}
catch (InvalidOperationException ex)
{
    // Log the full response for diagnosis
    _logger.LogError("IPC 请求失败:Success={Success}, Code={Code}, Msg={Msg}",
        response.Success, response.ErrorCode, response.ErrorMessage);
    throw;
}

Prevention

When it happens

Trigger: A remote IPC handler returned an InstanceIpcEnvelope with Success = false (or null) but did not populate ErrorCode or ErrorMessage. In normal operation, failures are created via InstanceIpcEnvelope.Failure(request, errorCode, errorMessage) which always sets both. This generic fallback fires only when the response was constructed differently or deserialized from a peer that omitted error details.

Common situations: A peer running a different version whose failure response schema omits error fields; a deserialization issue where ErrorCode/ErrorMessage were present in JSON but didn't map due to casing; a bug in a custom handler that returns a bare failure envelope; the remote's HandleAsync catch block returned Failure but the error message extraction (exception.GetBaseException().Message) returned null.

Related errors


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