{"record":{"id":"20603e944b39e606","repo":"embassy-rs/embassy","slug":"unwrap-of-failed","errorCode":null,"errorMessage":"unwrap of `{}` failed: {:?}","messagePattern":"unwrap of `(.+?)` failed: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-net-wiznet/src/fmt.rs","lineNumber":189,"sourceCode":"    };\n}\n\n#[cfg(feature = \"defmt\")]\n#[collapse_debuginfo(yes)]\nmacro_rules! unwrap {\n    ($($x:tt)*) => {\n        ::defmt::unwrap!($($x)*)\n    };\n}\n\n#[cfg(not(feature = \"defmt\"))]\n#[collapse_debuginfo(yes)]\nmacro_rules! unwrap {\n    ($arg:expr) => {\n        match $crate::fmt::Try::into_result($arg) {\n            ::core::result::Result::Ok(t) => t,\n            ::core::result::Result::Err(e) => {\n                ::core::panic!(\"unwrap of `{}` failed: {:?}\", ::core::stringify!($arg), e);\n            }\n        }\n    };\n    ($arg:expr, $($msg:expr),+ $(,)? ) => {\n        match $crate::fmt::Try::into_result($arg) {\n            ::core::result::Result::Ok(t) => t,\n            ::core::result::Result::Err(e) => {\n                ::core::panic!(\"unwrap of `{}` failed: {}: {:?}\", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);\n            }\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, Eq, PartialEq)]\npub struct NoneError;\n\npub trait Try {\n    type Ok;","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-net-wiznet/src/fmt.rs#L171-L207","documentation":"This panic comes from embassy-net-wiznet's internal `unwrap!` macro (the non-defmt variant) when the expression passed to `unwrap!(...)` is an `Err` or `None`. The macro converts the value via `fmt::Try::into_result` and, on failure, panics with the stringified expression and the debug-formatted error. It is a deliberate fail-fast on operations the driver assumed could not fail or that the caller was expected to handle.","triggerScenarios":"Any call to `unwrap!(expr)` in the wiznet driver where `expr: Result<T,E>` is `Err(e)` or `expr: Option<T>` is `None` — e.g. unwrapping SPI transfer results, buffer queue pops, or device register reads during W5500 Ethernet chip operations.","commonSituations":"Bare-metal/embassy firmware using the Wiznet W5500 driver where an SPI transaction failed, the chip was miswired/reset, or an internal buffer/queue returned None. Because this is the `not(feature = \"defmt\")` build, the panic message prints via core fmt instead of defmt.","solutions":["Identify the real `unwrap!` call site: the panic string includes the stringified expression; search embassy-net-wiznet/src for that expression.","Fix the underlying cause (usually SPI bus errors, wrong chip-select/speed wiring, or missing device reset) rather than the unwrap itself.","Enable the `defmt` feature if you want `defmt::unwrap!` semantics and richer logging in embedded builds.","As a last resort, fork/patch the driver to propagate the error instead of unwrapping."],"exampleFix":"// before: driver panics inside unwrap!\nlet res = unwrap!(self.spi.read_write(&mut buf[..]), \"spi read_write\");\n// after: propagate SPI errors instead of panicking\nlet res = self.spi.read_write(&mut buf[..]).map_err(|_| Error::Spi)?;","handlingStrategy":"try-catch","validationCode":"// In no_std/panic=abort firmware you cannot catch; pre-validate hardware state:\nif !self.device_ready() { return Err(Error::Spi); }","typeGuard":"fn is_ok<T, E>(r: &Result<T, E>) -> bool { r.is_ok() }","tryCatchPattern":"// Firmware: set a panic hook to log the unwrap expression and reset/defuse.\n#[panic_handler] or `panic_hook`: log panic info, then reset the W5500 and reinit SPI.","preventionTips":["Verify SPI wiring, chip-select, and clock speed against W5500 datasheet limits before bring-up.","Add a reset-and-reinit routine for the Ethernet chip on first failure.","Enable defmt logging to see driver internals before failures escalate to unwrap panics.","Patch or wrap driver calls to propagate errors instead of unwrapping."],"tags":["embedded","rust","panic","unwrap","network-driver"],"backgroundTag":"internal-invariant-violation","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}