From ad256997d699d80b5b7dd86206736cdffd7a25e1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 13 Aug 2022 23:03:48 +0200 Subject: [PATCH] chore(solc): improve io error for bad symlinks (#1594) --- ethers-solc/src/error.rs | 17 ++++++++++++++++- ethers-solc/src/resolver/mod.rs | 10 ++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ethers-solc/src/error.rs b/ethers-solc/src/error.rs index edfd4e89..fc00601c 100644 --- a/ethers-solc/src/error.rs +++ b/ethers-solc/src/error.rs @@ -1,5 +1,8 @@ use semver::Version; -use std::{io, path::PathBuf}; +use std::{ + io, + path::{Path, PathBuf}, +}; use thiserror::Error; pub type Result = std::result::Result; @@ -27,6 +30,8 @@ pub enum SolcError { /// Failed to resolve a file #[error("Failed to resolve file: {0}.\n Check configured remappings.")] Resolve(SolcIoError), + #[error("File could not be resolved due to broken symlink: {0}.")] + ResolveBadSymlink(SolcIoError), #[cfg(feature = "svm-solc")] #[error(transparent)] SvmError(#[from] svm::SolcVmError), @@ -83,6 +88,16 @@ impl SolcIoError { pub fn new(io: io::Error, path: impl Into) -> Self { Self { io, path: path.into() } } + + /// The path at which the error occurred + pub fn path(&self) -> &Path { + &self.path + } + + /// The underlying `io::Error` + pub fn source(&self) -> &io::Error { + &self.io + } } impl From for io::Error { diff --git a/ethers-solc/src/resolver/mod.rs b/ethers-solc/src/resolver/mod.rs index 3c68f2d6..945e30e8 100644 --- a/ethers-solc/src/resolver/mod.rs +++ b/ethers-solc/src/resolver/mod.rs @@ -818,9 +818,15 @@ pub struct Node { impl Node { /// Reads the content of the file and returns a [Node] containing relevant information - pub fn read(file: impl AsRef) -> crate::Result { + pub fn read(file: impl AsRef) -> Result { let file = file.as_ref(); - let source = Source::read(file).map_err(SolcError::Resolve)?; + let source = Source::read(file).map_err(|err| { + if !err.path().exists() && err.path().is_symlink() { + SolcError::ResolveBadSymlink(err) + } else { + SolcError::Resolve(err) + } + })?; let data = SolData::parse(source.as_ref(), file); Ok(Self { path: file.to_path_buf(), source, data }) }