Closed
Description
With this code:
let file_name = Path::new("/tmp/does_not_exist/test");
match fs::File::create(file_name) {
Ok(_) => (),
Err(e) => {
println!("Sync: Error opening file {}: {}", file_name.display(), e);
}
};
async_std::task::block_on(async {
match async_std::fs::File::create(file_name).await {
Ok(_) => (),
Err(e) => {
println!("Async: Error opening file {}: {}", file_name.display(), e);
}
};
});
We get this output:
Sync: Error opening file /tmp/does_not_exist/test: No such file or directory (os error 2)
Async: Error opening file /tmp/does_not_exist/test: could not create `/tmp/does_not_exist/test`
There are two problems with this:
- The async version doesn't output the actual reason that the operation failed
- The async version adds the filename as context. While arguably the std version should do that as well - it doesn't, meaning that if you use the async API in the same way as the sync API, it prints the filename twice.
The first point is the most important. Although more error information is available by inspecting kind
or source
, I think the Display
implementation should include the actual cause of the error.
I don't view the second point as critical, as long as async_std supplies the context for every relevant API and also documents that divergance from std::fs
on the doc page for async_std::fs
(although I guess a major selling point of async-std is that the API mirrors std).