You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在出现错误并退出(代码:2)后保持Golang WebAssembly实例持续运行

How to keep Go WebAssembly instance running despite invalid input (non-Uint8Array) to sendBytes?

Problem Statement

I've written a Go WebAssembly function to receive byte data from JavaScript, but when I pass non-Uint8Array data to it, the entire WASM instance crashes and I have to restart it. Here's my code:

func sendBytes(this js.Value, args []js.Value) interface{} { 
    if len(args) < 1 { 
        return 0 
    } 
    array := args[0] 
    fmt.Println(array.Type()) 
    buf := make([]byte, array.Length()) 
    n := js.CopyBytesToGo(buf, array) 
    fmt.Println(buf) 
    return n 
} 
func registerCallbacks() { 
    js.Global().Set("sendBytes", js.FuncOf(sendBytes)) 
}

How can I ensure the WASM instance keeps running no matter what errors occur?

Answer

Great question—this is a super common pitfall when working with Go WASM and JavaScript interop! The core issue here is that js.CopyBytesToGo will panic if you pass a value that isn't a valid Uint8Array (or compatible typed array with a byte-aligned layout). Unrecovered panics in Go WASM take the entire instance down, so we need two key fixes: input validation and panic recovery.

Here's how to make your function crash-resistant:

1. Validate input type before processing

First, we'll add a check to ensure the input is actually a Uint8Array before attempting any byte copying. This blocks invalid inputs from ever reaching the panic-prone function:

func sendBytes(this js.Value, args []js.Value) interface{} { 
    // Check for missing input
    if len(args) < 1 { 
        return map[string]interface{}{
            "success": false,
            "error":   "no input value provided",
        }
    } 

    input := args[0]
    uint8ArrayConstructor := js.Global().Get("Uint8Array")
    
    // Verify the input is a Uint8Array instance
    if input.Type() != js.TypeObject || !input.InstanceOf(uint8ArrayConstructor) {
        return map[string]interface{}{
            "success": false,
            "error":   "input must be a Uint8Array",
        }
    }

    // Now we can safely process the valid input
    buf := make([]byte, input.Length()) 
    bytesCopied := js.CopyBytesToGo(buf, input) 
    fmt.Println("Received bytes:", buf) 

    return map[string]interface{}{
        "success":      true,
        "bytesCopied":  bytesCopied,
        "receivedData": buf, // Optional: return data back to JS if needed
    }
}

2. Add a panic recovery safety net

Even with strict type checks, edge cases (like a detached typed array or unexpected JS value quirks) could still trigger a panic. Adding a deferred recover ensures any panics are caught, logged, and don't take down the entire WASM instance:

func sendBytes(this js.Value, args []js.Value) interface{} { 
    // Use a named return value to easily update results in the recover handler
    var result = map[string]interface{}{"success": true}

    // Catch and recover from any unexpected panics
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Recovered from panic in sendBytes: %v\n", r)
            result["success"] = false
            result["error"] = "unexpected error processing input"
        }
    }()

    // Input validation
    if len(args) < 1 { 
        result["success"] = false
        result["error"] = "no input value provided"
        return result
    } 

    input := args[0]
    uint8ArrayConstructor := js.Global().Get("Uint8Array")
    
    if input.Type() != js.TypeObject || !input.InstanceOf(uint8ArrayConstructor) {
        result["success"] = false
        result["error"] = "input must be a Uint8Array"
        return result
    }

    // Safe byte copying
    buf := make([]byte, input.Length()) 
    bytesCopied := js.CopyBytesToGo(buf, input) 
    fmt.Println("Received bytes:", buf) 

    result["bytesCopied"] = bytesCopied
    result["receivedData"] = buf
    return result
}

3. Return structured responses to JavaScript

Instead of returning a plain number like 0, using a structured object with success/error flags makes it easy for your JavaScript code to handle failures gracefully without guessing what went wrong.

Why this works

  • Type validation filters out invalid inputs before they can cause a panic.
  • Panic recovery acts as a safety net for unexpected edge cases, keeping the WASM instance alive.
  • Structured responses improve clarity and interoperability between Go WASM and JavaScript.

内容的提问来源于stack exchange,提问作者Igor65777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:32:35