{"record":{"id":"b1a24d82951b4e61","repo":"a-b-street/abstreet","slug":"bad-distanceinterval","errorCode":null,"errorMessage":"Bad DistanceInterval {} .. {}","messagePattern":"Bad DistanceInterval (.+?) \\.\\. (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sim/src/lib.rs","lineNumber":538,"sourceCode":"    pub fn percent_clamp_end(&self, t: Time) -> f64 {\n        if t > self.end {\n            return 1.0;\n        }\n        self.percent(t)\n    }\n}\n\n#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]\npub(crate) struct DistanceInterval {\n    // TODO Private fields\n    pub start: Distance,\n    pub end: Distance,\n}\n\nimpl DistanceInterval {\n    pub fn new_driving(start: Distance, end: Distance) -> DistanceInterval {\n        if end < start {\n            panic!(\"Bad DistanceInterval {} .. {}\", start, end);\n        }\n        DistanceInterval { start, end }\n    }\n\n    pub fn new_walking(start: Distance, end: Distance) -> DistanceInterval {\n        // start > end is fine, might be contraflow.\n        DistanceInterval { start, end }\n    }\n\n    pub fn lerp(&self, x: f64) -> Distance {\n        assert!((0.0..=1.0).contains(&x));\n        self.start + x * (self.end - self.start)\n    }\n\n    pub fn length(&self) -> Distance {\n        (self.end - self.start).abs()\n    }\n}","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/sim/src/lib.rs#L520-L556","documentation":"DistanceInterval::new_driving validates that the driving interval runs forward along a lane: end must be >= start. Driving distances must be monotonic, so a reversed interval panics at construction instead of yielding a negative-length slice.","triggerScenarios":"Calling DistanceInterval::new_driving(start, end) with end < start, typically from mixed-up along-lane distances. Note new_walking deliberately permits start > end (contraflow), so only the driving constructor panics.","commonSituations":"Path-following code that computes start/end distances from wrong direction of traversal; agents routed the wrong way on one-way lanes; unit confusion between lane-length fractions and absolute distances.","solutions":["Use new_walking instead if the interval may be reversed (contraflow) by design","Check that end is measured further along the same lane than start","Clamp or swap the distances before constructing"],"exampleFix":"// before\nlet d = DistanceInterval::new_driving(far, near);\n// after\nlet d = if far < near { DistanceInterval::new_driving(far, far.max(near)) } else { DistanceInterval::new_driving(near, far) };","handlingStrategy":"validation","validationCode":"if end >= start { let d = DistanceInterval::new_driving(start, end); }","typeGuard":"fn valid_driving_interval(start: Distance, end: Distance) -> bool { end >= start }","tryCatchPattern":"let d = std::panic::catch_unwind(|| DistanceInterval::new_driving(start, end)).ok();","preventionTips":["Use new_walking for any interval that may be reversed (contraflow)","Clamp distances against map.get_l(lane).length() before constructing"],"tags":["rust","panic","argument-validation","simulation"],"backgroundTag":"invalid-argument-value","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}