Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/next-core/src/next_client_chunks/with_chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ impl EcmascriptChunkItem for WithChunksChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.inner.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let inner = self.inner.await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ impl EcmascriptChunkItem for WithClientChunksChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.inner.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let inner = self.inner.await?;
Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-tasks-memory/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Output {
pub fn read_untracked(&mut self) -> Result<RawVc> {
match &self.content {
OutputContent::Empty => Err(anyhow!("Output is empty")),
OutputContent::Error(err) => Err(err.clone().into()),
OutputContent::Error(err) => Err(anyhow::Error::new(err.clone())),
OutputContent::Link(raw_vc) => Ok(*raw_vc),
OutputContent::Panic(Some(message)) => Err(anyhow!("A task panicked: {message}")),
OutputContent::Panic(None) => Err(anyhow!("A task panicked")),
Expand Down
20 changes: 19 additions & 1 deletion crates/turbo-tasks-memory/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,19 @@ impl Task {
}
}

pub(crate) fn get_function_name(&self) -> Option<&'static str> {
if let TaskType::Persistent(ty) = &self.ty {
match &**ty {
PersistentTaskType::Native(native_fn, _)
| PersistentTaskType::ResolveNative(native_fn, _) => {
return Some(&registry::get_function(*native_fn).name);
}
_ => {}
}
}
None
}

pub(crate) fn get_description(&self) -> String {
match &self.ty {
TaskType::Root(..) => format!("[{}] root", self.id),
Expand Down Expand Up @@ -700,7 +713,12 @@ impl Task {
match state.state_type {
InProgress { .. } => match result {
Ok(Ok(result)) => state.output.link(result, turbo_tasks),
Ok(Err(err)) => state.output.error(err, turbo_tasks),
Ok(Err(mut err)) => {
if let Some(name) = self.get_function_name() {
err = err.context(format!("Execution of {} failed", name));
}
state.output.error(err, turbo_tasks)
}
Err(message) => state.output.panic(message, turbo_tasks),
},
InProgressDirty { .. } => {
Expand Down
6 changes: 4 additions & 2 deletions crates/turbo-tasks/src/native_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
sync::atomic::{AtomicUsize, Ordering},
};

use anyhow::Result;
use anyhow::{Context, Result};

use crate::{
self as turbo_tasks, registry::register_function, task_input::TaskInput, util::SharedError,
Expand Down Expand Up @@ -56,7 +56,9 @@ impl NativeFunction {

/// Creates a functor for execution from a fixed set of inputs.
pub fn bind(&'static self, inputs: &Vec<TaskInput>) -> NativeTaskFn {
match (self.bind_fn)(inputs) {
match (self.bind_fn)(inputs)
.with_context(|| format!("Error during argument binding of {}", self.name))
{
Ok(native_fn) => Box::new(move || {
let r = native_fn();
if cfg!(feature = "log_function_stats") {
Expand Down
7 changes: 2 additions & 5 deletions crates/turbo-tasks/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ pub struct SharedError {

impl SharedError {
pub fn new(err: Error) -> Self {
match err.downcast::<SharedError>() {
Ok(shared) => shared,
Err(plain) => Self {
inner: Arc::new(plain),
},
Self {
inner: Arc::new(err),
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion crates/turbopack-core/src/chunk/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
pub mod dev;
pub mod optimize;

use std::{collections::VecDeque, fmt::Debug};
use std::{
collections::VecDeque,
fmt::{Debug, Display},
};

use anyhow::{anyhow, Result};
use indexmap::IndexSet;
Expand Down Expand Up @@ -32,6 +35,23 @@ pub enum ModuleId {
String(String),
}

impl Display for ModuleId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ModuleId::Number(i) => write!(f, "{}", i),
ModuleId::String(s) => write!(f, "{}", s),
}
}
}

#[turbo_tasks::value_impl]
impl ValueToString for ModuleId {
#[turbo_tasks::function]
fn to_string(&self) -> StringVc {
StringVc::cell(self.to_string())
}
}

impl ModuleId {
pub fn parse(id: &str) -> Result<ModuleId> {
Ok(match id.parse::<u32>() {
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-css/src/module_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ impl EcmascriptChunkItem for ModuleChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.module.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let parsed = self.module.parse().await?;
Expand Down
33 changes: 32 additions & 1 deletion crates/turbopack-ecmascript/src/chunk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use turbopack_core::{
asset::{children_from_asset_references, content_to_details, IntrospectableAssetVc},
Introspectable, IntrospectableChildrenVc, IntrospectableVc,
},
issue::{code_gen::CodeGenerationIssue, IssueSeverity},
reference::{AssetReferenceVc, AssetReferencesVc},
source_map::{GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc, SourceMapVc},
version::{
Expand Down Expand Up @@ -490,7 +491,36 @@ impl EcmascriptChunkContentEntryVc {
#[turbo_tasks::function]
async fn new(chunk_item: EcmascriptChunkItemVc) -> Result<Self> {
let content = chunk_item.content();
let factory = module_factory(content);
let factory = match module_factory(content).resolve().await {
Ok(factory) => factory,
Err(error) => {
let id = chunk_item.id().to_string().await;
let id = id.as_ref().map_or_else(|_| "unknown", |id| &**id);
let mut error_message =
format!("An error occurred while generating the chunk item {}", id);
for err in error.chain() {
write!(error_message, "\n at {}", err)?;
}
let js_error_message = serde_json::to_string(&error_message)?;
let issue = CodeGenerationIssue {
severity: IssueSeverity::Error.cell(),
path: chunk_item.related_path(),
title: StringVc::cell("Code generation for chunk item errored".to_string()),
message: StringVc::cell(error_message),
}
.cell();
issue.as_issue().emit();
let mut code = CodeBuilder::default();
code += "(() => {{\n\n";
write!(
code,
"throw new Error({error});\n",
error = &js_error_message
)?;
code += "\n}})";
code.build().cell()
}
};
let id = chunk_item.id().await?;
let code = factory.await?;
let hash = hash_xxh3_hash64(code.source_code());
Expand Down Expand Up @@ -1196,6 +1226,7 @@ pub struct EcmascriptChunkItemOptions {

#[turbo_tasks::value_trait]
pub trait EcmascriptChunkItem: ChunkItem + ValueToString {
fn related_path(&self) -> FileSystemPathVc;
fn content(&self) -> EcmascriptChunkItemContentVc;
fn chunking_context(&self) -> ChunkingContextVc;
fn id(&self) -> ModuleIdVc {
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-ecmascript/src/chunk_group_files_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ impl EcmascriptChunkItem for ChunkGroupFilesChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.inner.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let chunks = self.inner.chunks();
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-ecmascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ impl EcmascriptChunkItem for ModuleChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.module.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let AnalyzeEcmascriptModuleResult {
Expand Down
17 changes: 13 additions & 4 deletions crates/turbopack-ecmascript/src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{future::Future, sync::Arc};

use anyhow::Result;
use anyhow::{anyhow, Context, Result};
use swc_core::{
base::SwcComments,
common::{
Expand All @@ -19,7 +19,7 @@ use swc_core::{
visit::VisitMutWith,
},
};
use turbo_tasks::{primitives::U64Vc, Value};
use turbo_tasks::{primitives::U64Vc, Value, ValueToString};
use turbo_tasks_fs::{FileContent, FileSystemPath, FileSystemPathVc};
use turbo_tasks_hash::{DeterministicHasher, Xxh3Hash64Hasher};
use turbopack_core::{
Expand Down Expand Up @@ -141,15 +141,24 @@ pub async fn parse(
FileContent::Content(file) => match file.content().to_str() {
Ok(string) => {
let transforms = &*transforms.await?;
parse_content(
match parse_content(
string.into_owned(),
fs_path,
file_path_hash,
source,
ty,
transforms,
)
.await?
.await
{
Ok(result) => result,
Err(e) => {
return Err(e).context(anyhow!(
"Transforming and/or parsing of {} failed",
source.path().to_string().await?
));
}
}
}
// FIXME: report error
Err(_) => ParseResult::Unparseable.cell(),
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-env/src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ impl EcmascriptChunkItem for ProcessEnvChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.inner.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
let asset = self.inner.await?;
Expand Down
36 changes: 0 additions & 36 deletions crates/turbopack-json/src/issue.rs

This file was deleted.

39 changes: 15 additions & 24 deletions crates/turbopack-json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@

#![feature(min_specialization)]

pub mod issue;

use anyhow::Result;
use issue::{JsonIssue, JsonIssueVc};
use anyhow::{Context, Result};
use turbo_tasks::{primitives::StringVc, ValueToString, ValueToStringVc};
use turbo_tasks_fs::FileSystemPathVc;
use turbopack_core::{
Expand Down Expand Up @@ -104,30 +101,24 @@ impl EcmascriptChunkItem for JsonChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.module.path()
}

#[turbo_tasks::function]
async fn content(&self) -> Result<EcmascriptChunkItemContentVc> {
// We parse to JSON and then stringify again to ensure that the
// JSON is valid.
let inner_code = match self.module.path().read_json().to_string().await {
Ok(content) => {
let js_str_content = serde_json::to_string(content.as_str())?;
format!("__turbopack_export_value__(JSON.parse({js_str_content}));",)
}
Err(error) => {
let error_message = format!("{:?}", error.to_string());
let js_error_message = serde_json::to_string(&format!(
"An error occurred while importing a JSON module: {}",
&error_message
))?;
let issue: JsonIssueVc = JsonIssue {
path: self.module.path(),
error_message: StringVc::cell(error_message),
}
.into();
issue.as_issue().emit();
format!("throw new Error({error})", error = &js_error_message,)
}
};
let content = self
.module
.path()
.read_json()
.to_string()
.await
.context("Unable to make a module from invalid JSON")?;
let js_str_content = serde_json::to_string(content.as_str())?;
let inner_code = format!("__turbopack_export_value__(JSON.parse({js_str_content}));");
Ok(EcmascriptChunkItemContent {
inner_code: inner_code.into(),
..Default::default()
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-mdx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ impl EcmascriptChunkItem for MdxChunkItem {
self.context
}

#[turbo_tasks::function]
fn related_path(&self) -> FileSystemPathVc {
self.module.path()
}

/// Once we have mdx contents, we should treat it as j|tsx components and
/// apply all of the ecma transforms
#[turbo_tasks::function]
Expand Down
Loading