mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Improving error message for invalid file types (#4216)
This commit is contained in:
parent
99b393110e
commit
d360e753bc
@ -5,10 +5,10 @@ use std::path::{Path, PathBuf};
|
|||||||
use chrono::{Datelike, Timelike};
|
use chrono::{Datelike, Timelike};
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use codespan_reporting::term;
|
use codespan_reporting::term;
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
use typst::diag::{bail, At, Severity, SourceDiagnostic, StrResult};
|
use typst::diag::{bail, FileError, Severity, SourceDiagnostic, StrResult};
|
||||||
use typst::eval::Tracer;
|
use typst::eval::Tracer;
|
||||||
use typst::foundations::{Datetime, Smart};
|
use typst::foundations::{Datetime, Smart};
|
||||||
use typst::layout::{Frame, PageRanges};
|
use typst::layout::{Frame, PageRanges};
|
||||||
@ -97,8 +97,10 @@ pub fn compile_once(
|
|||||||
Status::Compiling.print(command).unwrap();
|
Status::Compiling.print(command).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if main file can be read and opened.
|
if let Err(errors) = world
|
||||||
if let Err(errors) = world.source(world.main()).at(Span::detached()) {
|
.source(world.main())
|
||||||
|
.map_err(|err| hint_invalid_main_file(err, &command.common.input))
|
||||||
|
{
|
||||||
set_failed();
|
set_failed();
|
||||||
if watching {
|
if watching {
|
||||||
Status::Error.print(command).unwrap();
|
Status::Error.print(command).unwrap();
|
||||||
@ -483,6 +485,52 @@ fn open_file(open: Option<&str>, path: &Path) -> StrResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds useful hints when the main source file couldn't be read
|
||||||
|
/// and returns the final diagnostic.
|
||||||
|
fn hint_invalid_main_file(
|
||||||
|
file_error: FileError,
|
||||||
|
input: &Input,
|
||||||
|
) -> EcoVec<SourceDiagnostic> {
|
||||||
|
let is_utf8_error = matches!(file_error, FileError::InvalidUtf8);
|
||||||
|
let mut diagnostic =
|
||||||
|
SourceDiagnostic::error(Span::detached(), EcoString::from(file_error));
|
||||||
|
|
||||||
|
// Attempt to provide helpful hints for UTF-8 errors.
|
||||||
|
// Perhaps the user mistyped the filename.
|
||||||
|
// For example, they could have written "file.pdf" instead of
|
||||||
|
// "file.typ".
|
||||||
|
if is_utf8_error {
|
||||||
|
if let Input::Path(path) = input {
|
||||||
|
let extension = path.extension();
|
||||||
|
if extension.is_some_and(|extension| extension == "typ") {
|
||||||
|
// No hints if the file is already a .typ file.
|
||||||
|
// The file is indeed just invalid.
|
||||||
|
return eco_vec![diagnostic];
|
||||||
|
}
|
||||||
|
|
||||||
|
match extension {
|
||||||
|
Some(extension) => {
|
||||||
|
diagnostic.hint(eco_format!(
|
||||||
|
"a file with the `.{}` extension is not usually a Typst file",
|
||||||
|
extension.to_string_lossy()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
diagnostic
|
||||||
|
.hint("a file without an extension is not usually a Typst file");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if path.with_extension("typ").exists() {
|
||||||
|
diagnostic.hint("check if you meant to use the `.typ` extension instead");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eco_vec![diagnostic]
|
||||||
|
}
|
||||||
|
|
||||||
/// Print diagnostic messages to the terminal.
|
/// Print diagnostic messages to the terminal.
|
||||||
pub fn print_diagnostics(
|
pub fn print_diagnostics(
|
||||||
world: &SystemWorld,
|
world: &SystemWorld,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user