{"record":{"id":"21ac4b33db9eb733","repo":"ClementTsang/bottom","slug":"handle-error-err","errorCode":null,"errorMessage":"Handle error: {err:?}","messagePattern":"Handle error: (.+?)","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/collection/disks/windows/bindings.rs","lineNumber":83,"sourceCode":"    // SAFETY: This should be safe, we'll manually check the results and the\n    // arguments should be valid.\n    let ret = unsafe {\n        DeviceIoControl(\n            h_device,\n            IOCTL_DISK_PERFORMANCE,\n            None,\n            0,\n            Some(&mut disk_performance as *mut _ as _),\n            mem::size_of::<DISK_PERFORMANCE>() as u32,\n            Some(&mut bytes_returned),\n            None,\n        )\n    };\n\n    // SAFETY: This should be safe, we will check the result as well.\n    let handle_result = unsafe { CloseHandle(h_device) };\n    if let Err(err) = handle_result {\n        bail!(\"Handle error: {err:?}\");\n    }\n\n    if let Err(err) = ret {\n        bail!(\"Device I/O error: {err:?}\");\n    } else {\n        Ok(disk_performance)\n    }\n}\n\nfn current_volume(buffer: &[u16]) -> PathBuf {\n    let first_null = buffer.iter().position(|byte| *byte == 0x00).unwrap_or(0);\n    let path_string = OsString::from_wide(&buffer[..first_null]);\n\n    PathBuf::from(path_string)\n}\n\nfn close_find_handle(handle: HANDLE) -> anyhow::Result<()> {\n    // Clean up the handle.","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/ClementTsang/bottom/blob/b77d3175028849824e987c35177e8f61450d72e7/src/collection/disks/windows/bindings.rs#L65-L101","documentation":"volume_io calls CloseHandle(h_device) after the DeviceIoControl query and bails if the close itself fails. A failing CloseHandle on a volume handle means the kernel refused to release the handle (the error is carried from the windows crate's Err variant). The disk performance data is discarded even though it was likely retrieved successfully.","triggerScenarios":"CloseHandle returns Err — e.g. the handle was already invalidated/closed, an ERROR_INVALID_HANDLE from kernel-state races, or handle-table corruption under heavy concurrent volume queries.","commonSituations":"Monitoring daemons querying many volumes in tight loops with multiple threads touching the same volume handle table; rare kernel races on systems under extreme load; misbehaving filter drivers interfering with device handles.","solutions":["Retry the volume_io call; this is usually a transient handle-state race","Avoid calling disk I/O collection concurrently for the same volume from multiple threads","Check for third-party storage filter drivers (antivirus/encryption) interfering with device handles","Log and continue: the performance data was valid, so the close failure is rarely fatal to the caller"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// close failure is usually transient — retry the query once\nmatch volume_io(&volume) {\n    Ok(stats) => stats,\n    Err(e) if e.to_string().contains(\"Handle error\") => volume_io(&volume)\n        .unwrap_or_else(|e2| { log::debug!(\"{e2:?}\"); Default::default() }),\n    Err(e) => { log::debug!(\"{e:?}\"); Default::default() }\n}","preventionTips":["Avoid concurrent disk-I/O collection on the same volume","Retry transient handle errors once before surfacing","Watch for storage filter drivers that interfere with device handles"],"tags":["windows","win32","handle","disk-io"],"backgroundTag":"api-error-response","analyzedSha":"b77d3175028849824e987c35177e8f61450d72e7","analyzedAt":"2026-09-07T14:53:21.246Z","contentChangedAt":"2026-09-07T14:53:21.246Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}