Skip to content

Commit

Permalink
feat: basic error mechanism (#150)
Browse files Browse the repository at this point in the history
* feat: basic error support

* Tweak
  • Loading branch information
hyf0 committed Nov 3, 2023
1 parent 7ef1c20 commit 0c9ab02
Show file tree
Hide file tree
Showing 22 changed files with 217 additions and 81 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ resolver = "2"


[workspace.package]
edition = "2021"
homepage = "https://github.com/rolldown-rs/rolldown"
license = "MIT"
repository = "https://github.com/rolldown-rs/rolldown"
edition = "2021"
homepage = "https://github.com/rolldown-rs/rolldown"
license = "MIT"
repository = "https://github.com/rolldown-rs/rolldown"

[workspace.dependencies]
oxc = { version = "0.1.3", features = ["semantic", "formatter"] }
Expand All @@ -23,9 +23,10 @@ serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.87"
insta = "1.21.0"
testing_macros = "0.2.7"
scoped-tls = "1.0"
scoped-tls = "1.0.1"
string_wizard = { version = "0.0.9" }
async-trait = "0.1.62"
futures = "0.3.25"
itertools = "0.10.5"
thiserror = "1.0.50"
smallvec = "1.11.1"
1 change: 1 addition & 0 deletions crates/rolldown/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ futures = "0.3.25"
rayon = "1.6.0"
string_wizard = { workspace = true }
async-trait = { workspace = true }
smallvec = { workspace = true }

[dev_dependencies]
insta = { workspace = true }
Expand Down
8 changes: 2 additions & 6 deletions crates/rolldown/src/bundler/bundle/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use crate::bundler::{
},
utils::bitset::BitSet,
};
use anyhow::Ok;
use index_vec::{index_vec, IndexVec};
use rolldown_common::{ImportKind, ModuleId, SymbolRef};
use rustc_hash::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -254,10 +253,7 @@ impl<'a> Bundle<'a> {
ChunkGraph { chunks, module_to_chunk }
}

pub fn generate(
&mut self,
_input_options: &'a NormalizedInputOptions,
) -> anyhow::Result<Vec<Asset>> {
pub fn generate(&mut self, _input_options: &'a NormalizedInputOptions) -> Vec<Asset> {
use rayon::prelude::*;
let mut chunk_graph = self.generate_chunks();

Expand All @@ -284,6 +280,6 @@ impl<'a> Bundle<'a> {
})
.collect::<Vec<_>>();

Ok(assets)
assets
}
}
16 changes: 8 additions & 8 deletions crates/rolldown/src/bundler/bundler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rolldown_error::BuildError;
use sugar_path::AsPath;

use super::{
Expand All @@ -10,6 +11,8 @@ use super::{
};
use crate::{bundler::bundle::bundle::Bundle, plugin::plugin::BoxPlugin, InputOptions};

type BuildResult<T> = Result<T, Vec<BuildError>>;

pub struct Bundler {
input_options: NormalizedInputOptions,
_plugins: Vec<BoxPlugin>,
Expand All @@ -28,10 +31,7 @@ impl Bundler {
Self { input_options: normalized, _plugins: plugins }
}

pub async fn write(
&mut self,
output_options: crate::OutputOptions,
) -> anyhow::Result<Vec<Asset>> {
pub async fn write(&mut self, output_options: crate::OutputOptions) -> BuildResult<Vec<Asset>> {
let dir = output_options.dir.clone().unwrap_or_else(|| {
self.input_options.cwd.as_path().join("dist").to_string_lossy().to_string()
});
Expand All @@ -50,7 +50,7 @@ impl Bundler {
let dest = dir.as_path().join(&chunk.file_name);
if let Some(p) = dest.parent() {
if !p.exists() {
std::fs::create_dir_all(p)?;
std::fs::create_dir_all(p).unwrap();
}
};
std::fs::write(dest, &chunk.content).unwrap_or_else(|_| {
Expand All @@ -64,20 +64,20 @@ impl Bundler {
pub async fn generate(
&mut self,
output_options: crate::OutputOptions,
) -> anyhow::Result<Vec<Asset>> {
) -> BuildResult<Vec<Asset>> {
let normalized = NormalizedOutputOptions::from_output_options(output_options);
self.build(normalized).await
}

async fn build(&mut self, output_options: NormalizedOutputOptions) -> anyhow::Result<Vec<Asset>> {
async fn build(&mut self, output_options: NormalizedOutputOptions) -> BuildResult<Vec<Asset>> {
tracing::trace!("NormalizedInputOptions {:#?}", self.input_options);
tracing::trace!("NormalizedOutputOptions: {output_options:#?}",);

let mut graph = Graph::default();
graph.generate_module_graph(&self.input_options).await?;

let mut bundle = Bundle::new(&mut graph, &output_options);
let assets = bundle.generate(&self.input_options)?;
let assets = bundle.generate(&self.input_options);

Ok(assets)
}
Expand Down
19 changes: 11 additions & 8 deletions crates/rolldown/src/bundler/chunk/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ use rolldown_common::{ModuleId, SymbolRef};
use rustc_hash::FxHashMap;
use string_wizard::{Joiner, JoinerOptions};

use crate::bundler::{
chunk_graph::ChunkGraph,
graph::graph::Graph,
module::ModuleRenderContext,
options::{
file_name_template::FileNameRenderOptions, normalized_output_options::NormalizedOutputOptions,
use crate::{
bundler::{
chunk_graph::ChunkGraph,
graph::graph::Graph,
module::ModuleRenderContext,
options::{
file_name_template::FileNameRenderOptions, normalized_output_options::NormalizedOutputOptions,
},
utils::bitset::BitSet,
},
utils::bitset::BitSet,
error::BatchedResult,
};

use super::ChunkId;
Expand Down Expand Up @@ -54,7 +57,7 @@ impl Chunk {
}

#[allow(clippy::unnecessary_wraps)]
pub fn render(&self, graph: &Graph, chunk_graph: &ChunkGraph) -> anyhow::Result<String> {
pub fn render(&self, graph: &Graph, chunk_graph: &ChunkGraph) -> BatchedResult<String> {
use rayon::prelude::*;
let mut joiner = Joiner::with_options(JoinerOptions { separator: Some("\n".to_string()) });
joiner.append(self.render_imports_for_esm(graph, chunk_graph));
Expand Down
11 changes: 7 additions & 4 deletions crates/rolldown/src/bundler/graph/graph.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::{linker::Linker, linker_info::LinkingInfoVec, symbols::Symbols};
use crate::bundler::{
module::ModuleVec, module_loader::ModuleLoader,
options::normalized_input_options::NormalizedInputOptions, runtime::Runtime,
use crate::{
bundler::{
module::ModuleVec, module_loader::ModuleLoader,
options::normalized_input_options::NormalizedInputOptions, runtime::Runtime,
},
error::BatchedResult,
};
use rolldown_common::ModuleId;
use rustc_hash::FxHashSet;
Expand All @@ -20,7 +23,7 @@ impl Graph {
pub async fn generate_module_graph(
&mut self,
input_options: &NormalizedInputOptions,
) -> anyhow::Result<()> {
) -> BatchedResult<()> {
ModuleLoader::new(input_options, self).fetch_all_modules().await?;

tracing::trace!("{:#?}", self);
Expand Down
33 changes: 15 additions & 18 deletions crates/rolldown/src/bundler/module_loader/module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::bundler::module::Module;
use crate::bundler::options::normalized_input_options::NormalizedInputOptions;
use crate::bundler::runtime::RUNTIME_PATH;
use crate::bundler::utils::resolve_id::{resolve_id, ResolvedRequestInfo};
use crate::error::{BatchedErrors, BatchedResult};
use crate::SharedResolver;

pub struct ModuleLoader<'a> {
Expand All @@ -44,12 +45,10 @@ impl<'a> ModuleLoader<'a> {
}
}

pub async fn fetch_all_modules(&mut self) -> anyhow::Result<()> {
if self.input_options.input.is_empty() {
return Err(anyhow::format_err!("You must supply options.input to rolldown"));
}
pub async fn fetch_all_modules(&mut self) -> BatchedResult<()> {
assert!(!self.input_options.input.is_empty(), "You must supply options.input to rolldown");

let resolved_entries = self.resolve_entries();
let resolved_entries = self.resolve_entries()?;

let mut intermediate_modules: IndexVec<ModuleId, Option<Module>> =
IndexVec::with_capacity(resolved_entries.len() + 1 /* runtime */);
Expand Down Expand Up @@ -126,13 +125,13 @@ impl<'a> ModuleLoader<'a> {
}

#[allow(clippy::collection_is_never_read)]
fn resolve_entries(&mut self) -> Vec<(Option<String>, ResolvedRequestInfo)> {
fn resolve_entries(&mut self) -> BatchedResult<Vec<(Option<String>, ResolvedRequestInfo)>> {
let resolver = &self.resolver;

let resolved_ids =
block_on_spawn_all(self.input_options.input.iter().map(|input_item| async move {
let specifier = &input_item.import;
let resolve_id = resolve_id(resolver, specifier, None, false).await.unwrap();
let resolve_id = resolve_id(resolver, specifier, None, false).await?;

let Some(info) = resolve_id else {
return Err(BuildError::unresolved_entry(specifier));
Expand All @@ -145,18 +144,16 @@ impl<'a> ModuleLoader<'a> {
Ok((input_item.name.clone(), info))
}));

let mut errors = vec![];
let mut errors = BatchedErrors::default();

resolved_ids
.into_iter()
.filter_map(|handle| match handle {
Ok(id) => Some(id),
Err(e) => {
errors.push(e);
None
}
})
.collect()
let collected =
resolved_ids.into_iter().filter_map(|item| errors.take_err_from(item)).collect();

if errors.is_empty() {
Ok(collected)
} else {
Err(errors)
}
}

fn try_spawn_new_task(
Expand Down
44 changes: 44 additions & 0 deletions crates/rolldown/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use rolldown_error::BuildError;
use smallvec::SmallVec;

#[derive(Debug, Default)]
pub struct BatchedErrors(SmallVec<[BuildError; 1]>);

impl BatchedErrors {
pub fn with_error(err: BuildError) -> Self {
Self(smallvec::smallvec![err])
}

pub fn is_empty(&self) -> bool {
self.0.is_empty()
}

pub fn push(&mut self, err: BuildError) {
self.0.push(err);
}

/// Try to take the Err() of the given result and return Some(T) if it's Ok(T).
pub fn take_err_from<T>(&mut self, res: Result<T, rolldown_error::BuildError>) -> Option<T> {
match res {
Ok(t) => Some(t),
Err(err) => {
self.push(err);
None
}
}
}
}

pub type BatchedResult<T> = Result<T, BatchedErrors>;

impl From<BuildError> for BatchedErrors {
fn from(err: BuildError) -> Self {
Self::with_error(err)
}
}

impl From<BatchedErrors> for Vec<BuildError> {
fn from(errs: BatchedErrors) -> Self {
errs.0.into_vec()
}
}
1 change: 1 addition & 0 deletions crates/rolldown/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod bundler;
mod error;
mod plugin;

use std::sync::Arc;
Expand Down
8 changes: 5 additions & 3 deletions crates/rolldown/src/plugin/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::{borrow::Cow, fmt::Debug};

use crate::error::BatchedResult;

use super::{
args::{HookLoadArgs, HookResolveIdArgs, HookTransformArgs},
context::PluginContext,
output::{HookLoadOutput, HookResolveIdOutput},
};

pub type HookResolveIdReturn = rolldown_error::BuildResult<Option<HookResolveIdOutput>>;
pub type HookTransformReturn = rolldown_error::BuildResult<Option<HookLoadOutput>>;
pub type HookLoadReturn = rolldown_error::BuildResult<Option<HookLoadOutput>>;
pub type HookResolveIdReturn = BatchedResult<Option<HookResolveIdOutput>>;
pub type HookTransformReturn = BatchedResult<Option<HookLoadOutput>>;
pub type HookLoadReturn = BatchedResult<Option<HookLoadOutput>>;

#[async_trait::async_trait]
pub trait Plugin: Debug + Send + Sync {
Expand Down

0 comments on commit 0c9ab02

Please sign in to comment.