{"record":{"id":"cebd2b18f76286fa","repo":"Hmbown/CodeWhale","slug":"read-remaining-typed-input","errorCode":null,"errorMessage":"read remaining typed input","messagePattern":"read remaining typed input","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/palette/src/osc11_tests.rs","lineNumber":64,"sourceCode":"        let burst = [prefix.as_slice(), case.response, suffix.as_slice()].concat();\n        assert_eq!(\n            writer.write(&burst).expect(\"write one input burst\"),\n            burst.len()\n        );\n\n        // Keep the writer open: a buffered read-ahead must not be rescued by\n        // EOF/readable-HUP while the real tty would have no new bytes ready.\n        let (answered, reply, carried) = read_terminal_reply(\n            reader.as_raw_fd(),\n            case.query,\n            Duration::from_secs(1),\n            case.csi,\n        );\n        drop(writer);\n        let mut remaining = Vec::new();\n        reader\n            .read_to_end(&mut remaining)\n            .expect(\"read remaining typed input\");\n\n        assert!(\n            answered,\n            \"complete reply was already on the pipe: {:?}\",\n            case.response\n        );\n        assert_eq!(reply, case.reply, \"query {:?}\", case.query);\n        assert_eq!(\n            carried, prefix,\n            \"type-ahead before the reply must be replayable\"\n        );\n        assert_eq!(\n            remaining, suffix,\n            \"the input pump must still receive the exact suffix\"\n        );\n    }\n}\n","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/palette/src/osc11_tests.rs#L46-L82","documentation":"After the reply check, the test drops the writer and calls `reader.read_to_end(&mut remaining).expect(\"read remaining typed input\")` to drain the buffered typed suffix. The expect panics if the read fails — an I/O error on the pipe descriptor rather than a clean EOF, which is what a healthy pipe produces after the writer is dropped.","triggerScenarios":"The pipe's reader descriptor hitting an I/O error during drain (underlying fd closed twice, corruption from a prior failed read in `read_terminal_reply`); platform-specific errors on read_to_end after HUP.","commonSituations":"A previous step in the same test panicked and left the reader in a bad state while unwinding; sandboxed environments reporting unexpected errors on pipes; reading after an external close of the fd.","solutions":["Confirm `read_terminal_reply` left the reader fd valid and positioned after the reply","Drop the writer before read_to_end so EOF terminates the drain (the test already does this — verify ordering after edits)","Handle `ErrorKind::Interrupted` with a retry loop if signals are common in the environment","Inspect the io::Error message for the real cause (EBADF vs EIO)"],"exampleFix":"// before\nreader.read_to_end(&mut remaining).expect(\"read remaining typed input\");\n// after\nreader.read_to_end(&mut remaining)\n    .unwrap_or_else(|e| panic!(\"drain failed: {e}\"));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"reader.read_to_end(&mut remaining)\n    .unwrap_or_else(|e| panic!(\"pipe drain failed: {e}\"));","preventionTips":["Drop the writer before draining so read_to_end terminates at EOF","Verify earlier read steps (reply detection) didn't consume or corrupt the stream","In signal-heavy environments, loop on ErrorKind::Interrupted"],"tags":["rust","io","pipe","read"],"backgroundTag":"broken-pipe","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}