{"record":{"id":"a09e431caa94d5a5","repo":"flxzt/rnote","slug":"predefinedformat-try-from-u32-for-value-fa","errorCode":null,"errorMessage":"PredefinedFormat try_from::<u32>() for value {} failed","messagePattern":"PredefinedFormat try_from::<u32>\\(\\) for value (.+?) failed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/document/format.rs","lineNumber":48,"sourceCode":"    UsLetter,\n    #[serde(rename = \"us_legal\")]\n    UsLegal,\n    #[serde(rename = \"custom\")]\n    Custom,\n}\n\nimpl Default for PredefinedFormat {\n    fn default() -> Self {\n        Self::A3\n    }\n}\n\nimpl TryFrom<u32> for PredefinedFormat {\n    type Error = anyhow::Error;\n\n    fn try_from(value: u32) -> Result<Self, Self::Error> {\n        num_traits::FromPrimitive::from_u32(value).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"PredefinedFormat try_from::<u32>() for value {} failed\",\n                value\n            )\n        })\n    }\n}\n\nimpl PredefinedFormat {\n    pub fn size_mm(&self, orientation: Orientation) -> Option<Vector2> {\n        let mut size_portrait = match self {\n            PredefinedFormat::A6 => Some((105.0, 148.0)),\n            PredefinedFormat::A5 => Some((148.0, 210.0)),\n            PredefinedFormat::A4 => Some((210.0, 297.0)),\n            PredefinedFormat::A3 => Some((297.0, 420.0)),\n            PredefinedFormat::A2 => Some((420.0, 594.0)),\n            PredefinedFormat::UsLetter => Some((215.9, 279.4)),\n            PredefinedFormat::UsLegal => Some((215.9, 355.6)),\n            PredefinedFormat::Custom => None,","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/document/format.rs#L30-L66","documentation":"PredefinedFormat implements TryFrom<u32> through num_traits::FromPrimitive; a u32 that matches no PredefinedFormat variant yields this error. It protects against invalid numeric format identifiers read from stored preferences or documents.","triggerScenarios":"Calling PredefinedFormat::try_from(u32) with a value outside the defined variants, typically during deserialization of document/export preferences stored as integers.","commonSituations":"Files saved by another rnote version with different format enum ordering, corrupted or hand-edited .rnote files, and external code feeding unchecked integers into the engine.","solutions":["Validate the u32 is one of the defined PredefinedFormat discriminants before converting.","Open the file with the rnote version that created it, or migrate old enum values to current ones.","Use a default format on failure rather than failing the entire load.","Persist enums by stable name instead of raw integer discriminants when possible."],"exampleFix":"// before\nlet format = PredefinedFormat::try_from(raw_u32)?;\n// after\nlet format = PredefinedFormat::try_from(raw_u32)\n    .unwrap_or(PredefinedFormat::default());","handlingStrategy":"validation","validationCode":"fn is_valid_predefined_format(v: u32) -> bool {\n    PredefinedFormat::try_from(v).is_ok()\n}","typeGuard":"fn as_predefined_format(v: u32) -> Option<PredefinedFormat> {\n    num_traits::FromPrimitive::from_u32(v)\n}","tryCatchPattern":"match PredefinedFormat::try_from(raw) {\n    Ok(f) => f,\n    Err(_) => {\n        log::warn!(\"unknown predefined format {raw}; using default\");\n        PredefinedFormat::default()\n    }\n}","preventionTips":["Range-check integer format codes before calling the API","Keep enum discriminants stable across releases","Serialize by name where possible","Wrap conversions with unwrap_or(default) for preference loading"],"tags":["rust","enum","deserialization"],"backgroundTag":"invalid-enum-value","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}