I think that the std::env::VarError
type holds too little information. If the program errors on not being able to find an environmental variable, no useful information is given to the user.
std::env::var
takes the key as its parameter. If it returns VarError
, you already have the key, so it seems superfluous to duplicate it in VarError.
I don't think it's entirely superfluous. If you just ?
the error, and it gets printed, it'd be nice if it prints the variable name, without having to .with_context(|| format!("Error getting variable {varname}"))?
This seems like it has all the same tradeoffs as having file opens include the filename in errors: it adds overhead, but it makes error reporting better and easier.
Unfortunately, this would be a breaking change, because VarError
is a pub enum
and not #[non_exhaustive]
, so adding a field to VarError::NotPresent
or adding a new variant would break existing match
es.
On the other hand, there is reason to consider overhauling the environment access API due to memory safety issues:
If that were done, a new error type could be included as part of the new API. The existing VarError
is not Copy
and already contains an OsString
, so this would not remove any of its properties; but the new interface would either need a generic error type, or to copy the error, since the signature of env::var
is
pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError>
and the K
must be either moved as-is into the error value, or copied into an OsString
. The advantage of copying is simplicity and not exposing implementation-detail argument types, but it would be wasteful in the case where code is checking for the existence of environment variables and not stopping on error (e.g. imagine some moderately-frequently-called code which checks for an environment variable every time).
I think this breaks the zero-overhead principle. I don't need the path in the error if I'm the source of the error (as I have what I passed in available), but I do if I generated the path based on other information passed in (that the caller may not have access to). Basically, I'd rather explicitly add the context (with the explicit allocation if necessary) than have to think about such low-level things being inaccessible without considering allocations.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.