{"record":{"id":"c4471c77d141c40d","repo":"nautechsystems/nautilus_trader","slug":"failed-e-c4471c","errorCode":null,"errorMessage":"{FAILED}: {e}","messagePattern":"\\{FAILED\\}: \\{e\\}","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/types/currency.rs","lineNumber":296,"sourceCode":"impl FromStr for Currency {\n    type Err = CurrencyLookupError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let map_guard = CURRENCY_MAP.lock();\n        map_guard\n            .get(s)\n            .copied()\n            .ok_or_else(|| CurrencyLookupError::UnknownCode {\n                code: s.to_string(),\n            })\n    }\n}\n\nimpl<T: AsRef<str>> From<T> for Currency {\n    fn from(value: T) -> Self {\n        match Self::from_str(value.as_ref()) {\n            Ok(currency) => currency,\n            Err(e) => panic!(\"{FAILED}: {e}\"),\n        }\n    }\n}\n\nimpl Serialize for Currency {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,\n    {\n        self.code.serialize(serializer)\n    }\n}\n\nimpl<'de> Deserialize<'de> for Currency {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/types/currency.rs#L278-L314","documentation":"Currency::from<T: AsRef<str>> converts a string code (e.g. \"USD\", \"BTC\") into a Currency by delegating to from_str. If the string is not a known/registered currency code, from_str returns Err and this impl panics with {FAILED}: {e}. It exists so From can be infallible in signature, at the cost of a panic on unknown codes.","triggerScenarios":"Calling Currency::from(\"XYZ\") or let c: Currency = \"EUR_USD\".into() with a code that is not a built-in currency and has not been registered via Currency::register (or add_synthetic currency) beforehand.","commonSituations":"Hard-coding an exotic or mistyped currency code; loading venue configuration with an unsupported quote currency; upgrading nautilus versions where a previously registered currency is no longer pre-registered; reading currency codes from CSV/JSON without validation.","solutions":["Fix the currency code typo or use the exact ISO/exchange code","If the currency is legitimately unknown, register it first with Currency::register(new_currency) before converting","Use Currency::from_str(code) (returning Result) instead of the panicking From impl when input is untrusted","Add a validation check against the code format (3-letter uppercase ISO) before conversion"],"exampleFix":"// before\nlet currency: Currency = Currency::from(code); // panics on unknown code\n// after\nlet currency = Currency::from_str(code)\n    .unwrap_or_else(|_| {\n        let c = Currency::new(code, 8, 0, CurrencyType::CRYPTOCURRENCY);\n        Currency::register(c);\n        c\n    });","handlingStrategy":"validation","validationCode":"fn is_valid_currency_code(code: &str) -> bool {\n    code.len() <= 12 && code.chars().all(|c| c.is_ascii_uppercase() || c.is_ascii_digit())\n}","typeGuard":null,"tryCatchPattern":"match Currency::from_str(code) {\n    Ok(c) => c,\n    Err(e) => { log::error!(\"unknown currency '{code}': {e}\"); Currency::default() }\n}","preventionTips":["Use Currency::from_str (Result) for any untrusted or external currency code","Register custom/exotic currencies at startup before any conversion","Validate codes against ISO 4217 or the venue's supported list","Keep currency registration consistent across nautilus version upgrades"],"tags":["rust","currency","panic","parsing"],"backgroundTag":"invalid-identifier-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}