Skip to content

Commit 5843ca7

Browse files
committed
serialize TurboTasksExecutionErrors
1 parent a34548e commit 5843ca7

9 files changed

Lines changed: 58 additions & 66 deletions

File tree

turbopack/crates/turbo-tasks-backend/src/backend/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
14561456
fn task_execution_result(
14571457
&self,
14581458
task_id: TaskId,
1459-
result: Result<RawVc, Arc<TurboTasksExecutionError>>,
1459+
result: Result<RawVc, TurboTasksExecutionError>,
14601460
turbo_tasks: &dyn TurboTasksBackendApi<TurboTasksBackend<B>>,
14611461
) {
14621462
operation::UpdateOutputOperation::run(task_id, result, self.execute_context(turbo_tasks));
@@ -2566,7 +2566,7 @@ impl<B: BackingStorage> Backend for TurboTasksBackend<B> {
25662566
fn task_execution_result(
25672567
&self,
25682568
task_id: TaskId,
2569-
result: Result<RawVc, Arc<TurboTasksExecutionError>>,
2569+
result: Result<RawVc, TurboTasksExecutionError>,
25702570
turbo_tasks: &dyn TurboTasksBackendApi<Self>,
25712571
) {
25722572
self.0.task_execution_result(task_id, result, turbo_tasks);

turbopack/crates/turbo-tasks-backend/src/backend/operation/update_output.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use std::{mem::take, sync::Arc};
1+
use std::mem::take;
22

33
use anyhow::Result;
44
use serde::{Deserialize, Serialize};
5-
use turbo_tasks::{RawVc, TaskId, backend::TurboTasksExecutionError, util::SharedError};
5+
use turbo_tasks::{RawVc, TaskId, backend::TurboTasksExecutionError};
66

77
#[cfg(feature = "trace_task_dirty")]
88
use crate::backend::operation::invalidate::TaskDirtyCause;
@@ -44,7 +44,7 @@ pub enum UpdateOutputOperation {
4444
impl UpdateOutputOperation {
4545
pub fn run(
4646
task_id: TaskId,
47-
output: Result<RawVc, Arc<TurboTasksExecutionError>>,
47+
output: Result<RawVc, TurboTasksExecutionError>,
4848
mut ctx: impl ExecuteContext,
4949
) {
5050
let mut task = ctx.task(task_id, TaskDataCategory::All);
@@ -95,13 +95,12 @@ impl UpdateOutputOperation {
9595
panic!("Non-local tasks must not return a local Vc");
9696
}
9797
Err(err) => {
98-
let err = anyhow::Error::new(err);
9998
if let Some(OutputValue::Error(old_error)) = current_output {
100-
if old_error.eq_stack(&err) {
99+
if old_error == &err {
101100
return;
102101
}
103102
}
104-
OutputValue::Error(SharedError::new(err))
103+
OutputValue::Error(err)
105104
}
106105
};
107106
let old_content = task.insert(CachedDataItem::Output {

turbopack/crates/turbo-tasks-backend/src/data.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use rustc_hash::FxHashSet;
44
use serde::{Deserialize, Serialize};
55
use turbo_tasks::{
66
CellId, KeyValuePair, SessionId, TaskId, TraitTypeId, TypedSharedReference, ValueTypeId,
7+
backend::TurboTasksExecutionError,
78
event::{Event, EventListener},
89
registry,
9-
util::SharedError,
1010
};
1111

1212
use crate::{
@@ -56,7 +56,7 @@ pub struct CollectiblesRef {
5656
pub enum OutputValue {
5757
Cell(CellRef),
5858
Output(TaskId),
59-
Error(SharedError),
59+
Error(TurboTasksExecutionError),
6060
}
6161
impl OutputValue {
6262
fn is_transient(&self) -> bool {

turbopack/crates/turbo-tasks-backend/tests/panics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::panic;
22
use std::{
33
panic::{set_hook, take_hook},
4-
sync::{Arc, LazyLock},
4+
sync::LazyLock,
55
};
66

77
use anyhow::Result;
@@ -28,11 +28,11 @@ async fn test_panics_include_location() {
2828
let error = result.unwrap_err();
2929
let root_cause = error.root_cause();
3030

31-
let Some(panic) = root_cause.downcast_ref::<Arc<TurboTasksExecutionError>>() else {
31+
let Some(panic) = root_cause.downcast_ref::<TurboTasksExecutionError>() else {
3232
panic!("Expected a TurboTasksExecutionError");
3333
};
3434

35-
let TurboTasksExecutionError::Panic(panic) = &**panic else {
35+
let TurboTasksExecutionError::Panic(panic) = &*panic else {
3636
panic!("Expected a TurboTasksExecutionError::Panic");
3737
};
3838

turbopack/crates/turbo-tasks/src/backend.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
borrow::Cow,
23
error::Error,
34
fmt::{self, Debug, Display},
45
future::Future,
@@ -11,7 +12,9 @@ use std::{
1112
use anyhow::{Result, anyhow};
1213
use auto_hash_map::AutoMap;
1314
use rustc_hash::FxHasher;
15+
use serde::{Deserialize, Serialize};
1416
use tracing::Span;
17+
use turbo_rcstr::RcStr;
1518

1619
pub use crate::id::BackendJobId;
1720
use crate::{
@@ -401,9 +404,9 @@ pub type TaskCollectiblesMap = AutoMap<RawVc, i32, BuildHasherDefault<FxHasher>,
401404

402405
// Structurally and functionally similar to Cow<&'static, str> but explicitly notes the importance
403406
// of non-static strings potentially containing PII (Personal Identifiable Information).
404-
#[derive(Clone, Debug)]
407+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
405408
pub enum TurboTasksExecutionErrorMessage {
406-
PIISafe(&'static str),
409+
PIISafe(Cow<'static, str>),
407410
NonPIISafe(String),
408411
}
409412

@@ -416,16 +419,32 @@ impl Display for TurboTasksExecutionErrorMessage {
416419
}
417420
}
418421

419-
#[derive(Debug, Clone)]
422+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
420423
pub struct TurboTasksError {
421424
pub message: TurboTasksExecutionErrorMessage,
422425
pub source: Option<TurboTasksExecutionError>,
423426
}
424427

425-
#[derive(Clone, Debug)]
428+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
429+
pub struct TurboTaskContextError {
430+
pub task: RcStr,
431+
pub source: Option<TurboTasksExecutionError>,
432+
}
433+
434+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
426435
pub enum TurboTasksExecutionError {
427436
Panic(Arc<TurboTasksPanic>),
428437
Error(Arc<TurboTasksError>),
438+
TaskContext(Arc<TurboTaskContextError>),
439+
}
440+
441+
impl TurboTasksExecutionError {
442+
pub fn task_context(&self, task: impl Display) -> Self {
443+
TurboTasksExecutionError::TaskContext(Arc::new(TurboTaskContextError {
444+
task: RcStr::from(task.to_string()),
445+
source: Some(self.clone()),
446+
}))
447+
}
429448
}
430449

431450
impl Error for TurboTasksExecutionError {
@@ -435,6 +454,9 @@ impl Error for TurboTasksExecutionError {
435454
TurboTasksExecutionError::Error(error) => {
436455
error.source.as_ref().map(|s| s as &dyn Error)
437456
}
457+
TurboTasksExecutionError::TaskContext(context_error) => {
458+
context_error.source.as_ref().map(|s| s as &dyn Error)
459+
}
438460
}
439461
}
440462
}
@@ -446,6 +468,9 @@ impl Display for TurboTasksExecutionError {
446468
TurboTasksExecutionError::Error(error) => {
447469
write!(f, "{}", error.message)
448470
}
471+
TurboTasksExecutionError::TaskContext(context_error) => {
472+
write!(f, "Execution of {} failed", context_error.task)
473+
}
449474
}
450475
}
451476
}
@@ -534,7 +559,7 @@ pub trait Backend: Sync + Send {
534559
fn task_execution_result(
535560
&self,
536561
task_id: TaskId,
537-
result: Result<RawVc, Arc<TurboTasksExecutionError>>,
562+
result: Result<RawVc, TurboTasksExecutionError>,
538563
turbo_tasks: &dyn TurboTasksBackendApi<Self>,
539564
);
540565

turbopack/crates/turbo-tasks/src/capture_future.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
borrow::Cow,
23
cell::RefCell,
34
fmt::Display,
45
future::Future,
@@ -10,6 +11,7 @@ use std::{
1011

1112
use anyhow::Result;
1213
use pin_project_lite::pin_project;
14+
use serde::{Deserialize, Serialize};
1315
use turbo_tasks_malloc::{AllocationInfo, TurboMalloc};
1416

1517
use crate::{LAST_ERROR_LOCATION, backend::TurboTasksExecutionErrorMessage};
@@ -69,7 +71,7 @@ pub fn add_allocation_info(alloc_info: AllocationInfo) {
6971
});
7072
}
7173

72-
#[derive(Debug, Clone)]
74+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7375
pub struct TurboTasksPanic {
7476
pub message: TurboTasksExecutionErrorMessage,
7577
pub location: Option<String>,
@@ -101,7 +103,7 @@ impl<T, F: Future<Output = T>> Future for CaptureFuture<T, F> {
101103
let result =
102104
panic::catch_unwind(panic::AssertUnwindSafe(|| this.future.poll(cx))).map_err(|err| {
103105
let message = match err.downcast_ref::<&'static str>() {
104-
Some(s) => TurboTasksExecutionErrorMessage::PIISafe(s),
106+
Some(s) => TurboTasksExecutionErrorMessage::PIISafe(Cow::Borrowed(s)),
105107
None => match err.downcast_ref::<String>() {
106108
Some(s) => TurboTasksExecutionErrorMessage::NonPIISafe(s.clone()),
107109
None => {

turbopack/crates/turbo-tasks/src/manager.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::{
4343
task_statistics::TaskStatisticsApi,
4444
trace::TraceRawVcs,
4545
trait_helpers::get_trait_method,
46-
util::{IdFactory, SharedError, StaticOrArc},
46+
util::{IdFactory, StaticOrArc},
4747
vc::ReadVcFuture,
4848
};
4949

@@ -711,10 +711,8 @@ impl<B: Backend + 'static> TurboTasks<B> {
711711

712712
let result = match result {
713713
Ok(Ok(raw_vc)) => Ok(raw_vc),
714-
Ok(Err(err)) => Err(Arc::new(err.into())),
715-
Err(err) => {
716-
Err(Arc::new(TurboTasksExecutionError::Panic(Arc::new(err))))
717-
}
714+
Ok(Err(err)) => Err(err.into()),
715+
Err(err) => Err(TurboTasksExecutionError::Panic(Arc::new(err))),
718716
};
719717

720718
this.backend.task_execution_result(task_id, result, &*this);
@@ -807,24 +805,14 @@ impl<B: Backend + 'static> TurboTasks<B> {
807805

808806
let result = match result {
809807
Ok(Ok(raw_vc)) => Ok(raw_vc),
810-
Ok(Err(err)) => Err(Arc::new(err.into())),
811-
Err(err) => Err(Arc::new(TurboTasksExecutionError::Panic(Arc::new(err)))),
808+
Ok(Err(err)) => Err(err.into()),
809+
Err(err) => Err(TurboTasksExecutionError::Panic(Arc::new(err))),
812810
};
813811

814812
let local_task = LocalTask::Done {
815813
output: match result {
816814
Ok(raw_vc) => OutputContent::Link(raw_vc),
817-
Err(err) => match &*err {
818-
TurboTasksExecutionError::Error { .. } => {
819-
OutputContent::Error(SharedError::new(
820-
anyhow::Error::new(err)
821-
.context(format!("Execution of {ty} failed")),
822-
))
823-
}
824-
TurboTasksExecutionError::Panic(err) => {
825-
OutputContent::Panic(err.clone())
826-
}
827-
},
815+
Err(err) => OutputContent::Error(err.task_context(ty)),
828816
},
829817
};
830818

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1-
use std::{
2-
fmt::{self, Display},
3-
sync::Arc,
4-
};
1+
use std::fmt::{self, Display};
52

63
use anyhow::anyhow;
74

8-
use crate::{RawVc, TurboTasksPanic, util::SharedError};
5+
use crate::{RawVc, backend::TurboTasksExecutionError};
96

107
/// A helper type representing the output of a resolved task.
118
#[derive(Clone, Debug)]
129
pub enum OutputContent {
1310
Link(RawVc),
14-
Error(SharedError),
15-
Panic(Arc<TurboTasksPanic>),
11+
Error(TurboTasksExecutionError),
1612
}
1713

1814
impl OutputContent {
1915
pub fn as_read_result(&self) -> anyhow::Result<RawVc> {
2016
match &self {
2117
Self::Error(err) => Err(anyhow!(err.clone())),
2218
Self::Link(raw_vc) => Ok(*raw_vc),
23-
Self::Panic(err) => Err(anyhow!(err.clone())),
2419
}
2520
}
2621
}
@@ -30,7 +25,6 @@ impl Display for OutputContent {
3025
match self {
3126
Self::Link(raw_vc) => write!(f, "link {raw_vc:?}"),
3227
Self::Error(err) => write!(f, "error {err}"),
33-
Self::Panic(err) => write!(f, "panic {err}"),
3428
}
3529
}
3630
}

turbopack/crates/turbo-tasks/src/util.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,9 @@ impl SharedError {
3333
}
3434
}
3535

36-
pub fn eq_stack(&self, other: &anyhow::Error) -> bool {
37-
if self.to_string() != other.to_string() {
38-
return false;
39-
}
40-
let mut source = self.source();
41-
let mut other_source = other.source();
42-
loop {
43-
if source.is_none() && other_source.is_none() {
44-
return true;
45-
}
46-
let (Some(source_err), Some(other_source_err)) = (source, other_source) else {
47-
return false;
48-
};
49-
if source_err.to_string() != other_source_err.to_string() {
50-
return false;
51-
}
52-
source = source_err.source();
53-
other_source = other_source_err.source();
54-
}
36+
pub fn as_ref(&self) -> &(dyn StdError + 'static) {
37+
let err: &anyhow::Error = &self.inner;
38+
err.as_ref()
5539
}
5640
}
5741

0 commit comments

Comments
 (0)