From cef075df17749f02a3828d37692f4611f651864c Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 30 Oct 2023 01:53:28 +0000 Subject: [PATCH] fix(linter) Report error instead of panicing if the file fails to open (#1098) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #1093 e.g. ``` RUST_BACKTRACE=full cargo run --bin=oxc_cli lint -D=suspicious -D=style -D=restriction -D=pedantic -D=nursery -D=correctness -A=no-useless-escape ./tasks/coverage/typescript/tests/cases/compiler/corrupted.ts ``` Results in: ``` × Failed to open file help: Failed to open file "./tasks/coverage/typescript/tests/cases/compiler/corrupted.ts" with error "stream did not contain valid UTF-8" Finished in 10ms on 1 file with 126 rules using 12 threads. Found 0 warnings and 1 error. ``` --- crates/oxc_diagnostics/src/lib.rs | 5 +++++ crates/oxc_linter/src/service.rs | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/crates/oxc_diagnostics/src/lib.rs b/crates/oxc_diagnostics/src/lib.rs index 60add3abd..6003f8de8 100644 --- a/crates/oxc_diagnostics/src/lib.rs +++ b/crates/oxc_diagnostics/src/lib.rs @@ -25,3 +25,8 @@ use thiserror::Error; #[error("File is too long to fit on the screen")] #[diagnostic(help("{0:?} seems like a minified file"))] pub struct MinifiedFileError(pub PathBuf); + +#[derive(Debug, Error, Diagnostic)] +#[error("Failed to open file")] +#[diagnostic(help("Failed to open file {0:?} with error \"{1}\""))] +pub struct FailedToOpenFileError(pub PathBuf, pub std::io::Error); diff --git a/crates/oxc_linter/src/service.rs b/crates/oxc_linter/src/service.rs index 1900f82d7..91a1b027a 100644 --- a/crates/oxc_linter/src/service.rs +++ b/crates/oxc_linter/src/service.rs @@ -11,7 +11,7 @@ use rayon::{iter::ParallelBridge, prelude::ParallelIterator}; use rustc_hash::FxHashSet; use oxc_allocator::Allocator; -use oxc_diagnostics::{DiagnosticSender, DiagnosticService}; +use oxc_diagnostics::{DiagnosticSender, DiagnosticService, Error, FailedToOpenFileError}; use oxc_parser::Parser; use oxc_resolver::{ResolveOptions, Resolver}; use oxc_semantic::{ModuleRecord, SemanticBuilder}; @@ -140,8 +140,18 @@ impl Runtime { } let allocator = Allocator::default(); - let source_text = - fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read {path:?}")); + let source_text = match fs::read_to_string(path) { + Ok(source_text) => source_text, + Err(e) => { + tx_error + .send(Some(( + path.to_path_buf(), + vec![Error::new(FailedToOpenFileError(path.to_path_buf(), e))], + ))) + .unwrap(); + return; + } + }; let mut messages = self.process_source(path, &allocator, &source_text, source_type, true, tx_error);