{"record":{"id":"2aef699df06d774c","repo":"QuipNetwork/hashsigs-rs","slug":"err-message","errorCode":null,"errorMessage":"{err.message}","messagePattern":"\\{err\\.message\\}","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/wasm/mod.rs","lineNumber":1680,"sourceCode":"        stateful_policy: stateful_policy_name(account.statefulPolicy()),\n        next_stateful_leaf_index: account.nextStatefulLeafIndex(),\n        recovery_mode: account.recoveryMode(),\n    }\n}\n\n#[cfg(any(test, feature = \"wasm-bindings\"))]\nfn hex_string(bytes: &[u8]) -> String {\n    let mut out = String::from(\"0x\");\n    for byte in bytes {\n        use core::fmt::Write;\n        let _ = write!(out, \"{byte:02x}\");\n    }\n    out\n}\n\n#[cfg(feature = \"wasm-bindings\")]\nfn js_error(err: WasmErr) -> JsValue {\n    let e = js_sys::Error::new(&err.message);\n    if js_sys::Reflect::set(&e, &JsValue::from_str(\"code\"), &JsValue::from_str(err.code)).is_err() {\n        // Reflect::set failed, so the machine-readable code would be lost off the\n        // Error object. Fold it into the message so callers never lose it.\n        return js_sys::Error::new(&format!(\"[{}] {}\", err.code, err.message)).into();\n    }\n    e.into()\n}\n\n/// Build a serde-boundary error handler tagged with a STATIC argument label\n/// (e.g. `\"publicKey\"`). The label identifies which argument failed to\n/// deserialize without ever echoing the caller-supplied value (inputs include\n/// secret seeds). Returns a closure so call sites read\n/// `.map_err(js_error_from_serde(\"publicKey\"))`.\n#[cfg(feature = \"wasm-bindings\")]\nfn js_error_from_serde(label: &'static str) -> impl Fn(serde_wasm_bindgen::Error) -> JsValue {\n    move |_error| {\n        js_error(WasmErr {\n            code: ERR_INVALID_INPUT,","sourceCodeStart":1662,"sourceCodeEnd":1698,"githubUrl":"https://github.com/QuipNetwork/hashsigs-rs/blob/128c4ccb5c8ed038eb0b9953993dbbcd5c6c1b23/src/wasm/mod.rs#L1662-L1698","documentation":"This is a wasm-binding boundary error: any WasmErr produced inside the Rust library is converted into a JavaScript js_sys::Error whose message text is the underlying err.message. The library throws it so Rust-side failures (parsing, validation, internal errors) surface as native JS Error objects when the wasm API is called from JavaScript. A machine-readable `code` property is also attached to the Error via Reflect::set.","triggerScenarios":"Calling any wasm-exported API (compiled with the `wasm-bindings` feature) that internally returns a WasmErr; js_error() is invoked and creates the JS Error with the original err.message as its message and err.code as a `code` property.","commonSituations":"JS/TypeScript callers passing malformed input (bad publicKey, invalid serialized data) into wasm functions; callers reading only error.message and losing the `code` field because they don't know it's a custom property; environments where Reflect::set silently fails and the code is folded into the message as `[CODE] message` instead.","solutions":["Read error.code from the caught Error object to get the machine-readable error code, not just message.","If code is absent, parse the leading `[CODE] ` prefix from error.message (the fallback format used when Reflect::set fails).","Validate inputs in JS before calling the wasm API so WasmErr is never produced.","Check instanceof Error and the library's documented code values to branch on failure kinds."],"exampleFix":"// before\ncatch (e) {\n  console.log(e.message); // loses machine-readable code\n}\n// after\ncatch (e) {\n  const code = e.code ?? (/^\\[(.+?)\\] /.exec(e.message)?.[1]);\n  console.log(code, e.message);\n}","handlingStrategy":"try-catch","validationCode":"function assertValidPublicKey(s) {\n  if (typeof s !== 'string' || !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(s)) {\n    throw new TypeError('invalid publicKey argument');\n  }\n}","typeGuard":"function isWasmError(e) {\n  return e instanceof Error && (typeof e.code === 'string' || /^\\[.+?\\] /.test(e.message));\n}","tryCatchPattern":"try {\n  wasmApi(input);\n} catch (e) {\n  if (isWasmError(e)) {\n    const code = e.code ?? /^\\[(.+?)\\] /.exec(e.message)?.[1];\n    handleWasmFailure(code, e.message);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Validate arguments (formats, lengths, encodings) in JS before crossing the wasm boundary.","Always read error.code, not just message, when handling failures from this library.","Handle both message shapes: plain message and the `[CODE] message` fallback.","Keep the wasm bindings and JS wrapper versions in sync with documented error codes."],"tags":["wasm","javascript","error-mapping","wasm-bindings"],"backgroundTag":"api-error-response","analyzedSha":"128c4ccb5c8ed038eb0b9953993dbbcd5c6c1b23","analyzedAt":"2026-09-08T21:14:08.025Z","contentChangedAt":"2026-09-08T21:14:08.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}