Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd69e7d3

Browse files
authored
Extract engine errors as their ownJsError variant (#4534)
Related to#4515.Extracts a new `EngineError` type that is a new variant of `JsError`that cannot be converted to a `JsValue` using `into_erased`.This also makes `into_erased` fallible for `JsError`, which IMO is finesince we really want to make sure users handle engine errors gracefully.EDIT: Unfortunately, this doesn't fully address#4515 because the stackoverflows on the CI profile. Will open an issue related to that.
1 parent123cbf3 commitd69e7d3

File tree

25 files changed

+403
-287
lines changed

25 files changed

+403
-287
lines changed

‎core/engine/src/builtins/array/from_async.rs‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl Array {
113113
// This avoids allocating a new coroutine that will immediately finish.
114114
// Spec continues on `from_array_like`...
115115
ifletCoroutineState::Yielded(value) =
116-
from_array_like(Ok(JsValue::undefined()),&coroutine_state, context)
116+
from_array_like(Ok(JsValue::undefined()),&coroutine_state, context)?
117117
{
118118
// Coroutine yielded. We need to allocate it for a future execution.
119119
JsPromise::resolve(value, context).await_native(
@@ -159,7 +159,7 @@ impl Array {
159159
// This avoids allocating a new coroutine that will immediately finish.
160160
// Spec continues on `from_async_iterator`...
161161
ifletCoroutineState::Yielded(value) =
162-
from_async_iterator(Ok(JsValue::undefined()),&coroutine_state, context)
162+
from_async_iterator(Ok(JsValue::undefined()),&coroutine_state, context)?
163163
{
164164
JsPromise::resolve(value, context).await_native(
165165
NativeCoroutine::from_copy_closure_with_captures(
@@ -184,7 +184,7 @@ impl Array {
184184
// ii. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
185185
resolvers
186186
.reject
187-
.call(&JsValue::undefined(),&[err.to_opaque(context)], context)
187+
.call(&JsValue::undefined(),&[err.into_opaque(context)?], context)
188188
.expect("resolving functions cannot fail");
189189
}
190190

@@ -233,7 +233,7 @@ fn from_async_iterator(
233233
mutresult:JsResult<JsValue>,
234234
(global_state, state_machine):&(GlobalState,Cell<Option<AsyncIteratorStateMachine>>),
235235
context:&mutContext,
236-
) ->CoroutineState{
236+
) ->JsResult<CoroutineState>{
237237
let result =(||{
238238
letSome(mut sm) = state_machine.take()else{
239239
returnOk(CoroutineState::Done);
@@ -445,17 +445,17 @@ fn from_async_iterator(
445445
// AsyncBlockStart ( promiseCapability, asyncBody, asyncContext )
446446
// https://tc39.es/ecma262/#sec-asyncblockstart
447447
match result{
448-
Ok(cont) => cont,
448+
Ok(cont) =>Ok(cont),
449449

450450
// i. Assert: result is a throw completion.
451451
Err(err) =>{
452452
// ii. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
453453
global_state
454454
.resolvers
455455
.reject
456-
.call(&JsValue::undefined(),&[err.to_opaque(context)], context)
456+
.call(&JsValue::undefined(),&[err.into_opaque(context)?], context)
457457
.expect("resolving functions cannot fail");
458-
CoroutineState::Done
458+
Ok(CoroutineState::Done)
459459
}
460460
}
461461
}
@@ -490,7 +490,7 @@ fn from_array_like(
490490
mutresult:JsResult<JsValue>,
491491
(global_state, state_machine):&(GlobalState,Cell<Option<ArrayLikeStateMachine>>),
492492
context:&mutContext,
493-
) ->CoroutineState{
493+
) ->JsResult<CoroutineState>{
494494
let result:JsResult<_> =(||{
495495
letSome(mut sm) = state_machine.take()else{
496496
returnOk(CoroutineState::Done);
@@ -607,16 +607,16 @@ fn from_array_like(
607607
// AsyncBlockStart ( promiseCapability, asyncBody, asyncContext )
608608
// https://tc39.es/ecma262/#sec-asyncblockstart
609609
match result{
610-
Ok(cont) => cont,
610+
Ok(cont) =>Ok(cont),
611611
// i. Assert: result is a throw completion.
612612
Err(err) =>{
613613
// ii. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
614614
global_state
615615
.resolvers
616616
.reject
617-
.call(&JsValue::undefined(),&[err.to_opaque(context)], context)
617+
.call(&JsValue::undefined(),&[err.into_opaque(context)?], context)
618618
.expect("resolving functions cannot fail");
619-
CoroutineState::Done
619+
Ok(CoroutineState::Done)
620620
}
621621
}
622622
}

‎core/engine/src/builtins/async_generator/mod.rs‎

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl AsyncGenerator {
172172
|| state ==AsyncGeneratorState::SuspendedYield
173173
{
174174
// a. Perform AsyncGeneratorResume(generator, completion).
175-
Self::resume(&generator, completion, context);
175+
Self::resume(&generator, completion, context)?;
176176
}
177177

178178
// 11. Return promiseCapability.[[Promise]].
@@ -231,12 +231,12 @@ impl AsyncGenerator {
231231
generator.borrow_mut().data_mut().state =AsyncGeneratorState::DrainingQueue;
232232

233233
// b. Perform ! AsyncGeneratorAwaitReturn(generator).
234-
Self::await_return(&generator, return_value, context);
234+
Self::await_return(&generator, return_value, context)?;
235235
}
236236
// 9. Else if state is suspended-yield, then
237237
elseif state ==AsyncGeneratorState::SuspendedYield{
238238
// a. Perform AsyncGeneratorResume(generator, completion).
239-
Self::resume(&generator, completion, context);
239+
Self::resume(&generator, completion, context)?;
240240
}
241241
// 10. Else,
242242
// a. Assert: state is either executing or draining-queue.
@@ -323,7 +323,7 @@ impl AsyncGenerator {
323323
// 10. If state is suspended-yield, then
324324
if state ==AsyncGeneratorState::SuspendedYield{
325325
// a. Perform AsyncGeneratorResume(generator, completion).
326-
Self::resume(&generator, completion, context);
326+
Self::resume(&generator, completion, context)?;
327327
}
328328

329329
// 11. Else,
@@ -371,7 +371,7 @@ impl AsyncGenerator {
371371
done:bool,
372372
realm:Option<Realm>,
373373
context:&mutContext,
374-
){
374+
)->JsResult<()>{
375375
// 1. Assert: generator.[[AsyncGeneratorQueue]] is not empty.
376376
// 2. Let next be the first element of generator.[[AsyncGeneratorQueue]].
377377
// 3. Remove the first element from generator.[[AsyncGeneratorQueue]].
@@ -392,7 +392,7 @@ impl AsyncGenerator {
392392
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
393393
promise_capability
394394
.reject()
395-
.call(&JsValue::undefined(),&[e.to_opaque(context)], context)
395+
.call(&JsValue::undefined(),&[e.into_opaque(context)?], context)
396396
.expect("cannot fail per spec");
397397
}
398398

@@ -426,6 +426,7 @@ impl AsyncGenerator {
426426
}
427427
}
428428
// 8. Return unused.
429+
Ok(())
429430
}
430431

431432
/// `AsyncGeneratorResume ( generator, completion )`
@@ -442,7 +443,7 @@ impl AsyncGenerator {
442443
generator:&JsObject<AsyncGenerator>,
443444
completion:CompletionRecord,
444445
context:&mutContext,
445-
){
446+
)->JsResult<()>{
446447
// 1. Assert: generator.[[AsyncGeneratorState]] is either suspended-start or suspended-yield.
447448
assert!(matches!(
448449
generator.borrow().data().state,
@@ -463,7 +464,7 @@ impl AsyncGenerator {
463464
let(value, resume_kind) =match completion{
464465
CompletionRecord::Normal(val) =>(val,GeneratorResumeKind::Normal),
465466
CompletionRecord::Return(val) =>(val,GeneratorResumeKind::Return),
466-
CompletionRecord::Throw(err) =>(err.to_opaque(context),GeneratorResumeKind::Throw),
467+
CompletionRecord::Throw(err) =>(err.into_opaque(context)?,GeneratorResumeKind::Throw),
467468
};
468469

469470
// 3. Let callerContext be the running execution context.
@@ -480,6 +481,7 @@ impl AsyncGenerator {
480481
// 9. Assert: When we return here, genContext has already been removed from the execution context stack and
481482
// callerContext is the currently running execution context.
482483
// 10. Return unused.
484+
Ok(())
483485
}
484486

485487
/// `AsyncGeneratorAwaitReturn ( generator )`
@@ -496,7 +498,7 @@ impl AsyncGenerator {
496498
generator:&JsObject<AsyncGenerator>,
497499
value:JsValue,
498500
context:&mutContext,
499-
){
501+
)->JsResult<()>{
500502
// 1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
501503
assert_eq!(
502504
generator.borrow().data().state,
@@ -523,11 +525,11 @@ impl AsyncGenerator {
523525
// 8. If promiseCompletion is an abrupt completion, then
524526
Err(e) =>{
525527
// a. Perform AsyncGeneratorCompleteStep(generator, promiseCompletion, true).
526-
Self::complete_step(generator,Err(e),true,None, context);
528+
Self::complete_step(generator,Err(e),true,None, context)?;
527529
// b. Perform AsyncGeneratorDrainQueue(generator).
528-
Self::drain_queue(generator, context);
530+
Self::drain_queue(generator, context)?;
529531
// c. Return unused.
530-
return;
532+
returnOk(());
531533
}
532534
};
533535

@@ -549,10 +551,10 @@ impl AsyncGenerator {
549551
let result =Ok(args.get_or_undefined(0).clone());
550552

551553
// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
552-
Self::complete_step(generator, result,true,None, context);
554+
Self::complete_step(generator, result,true,None, context)?;
553555

554556
// d. Perform AsyncGeneratorDrainQueue(generator).
555-
Self::drain_queue(generator, context);
557+
Self::drain_queue(generator, context)?;
556558

557559
// e. Return undefined.
558560
Ok(JsValue::undefined())
@@ -580,10 +582,10 @@ impl AsyncGenerator {
580582
let result =Err(JsError::from_opaque(args.get_or_undefined(0).clone()));
581583

582584
// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
583-
Self::complete_step(generator, result,true,None, context);
585+
Self::complete_step(generator, result,true,None, context)?;
584586

585587
// d. Perform AsyncGeneratorDrainQueue(generator).
586-
Self::drain_queue(generator, context);
588+
Self::drain_queue(generator, context)?;
587589

588590
// e. Return undefined.
589591
Ok(JsValue::undefined())
@@ -596,14 +598,16 @@ impl AsyncGenerator {
596598
.build();
597599

598600
// 15. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
599-
// 16. Return unused.
600601
Promise::perform_promise_then(
601602
&promise,
602603
Some(on_fulfilled),
603604
Some(on_rejected),
604605
None,
605606
context,
606607
);
608+
609+
// 16. Return unused.
610+
Ok(())
607611
}
608612

609613
/// `AsyncGeneratorDrainQueue ( generator )`
@@ -616,7 +620,10 @@ impl AsyncGenerator {
616620
/// Panics if `generator` is not in the `DrainingQueue` state.
617621
///
618622
/// [spec]: https://tc39.es/ecma262/#sec-asyncgeneratordrainqueue
619-
pub(crate)fndrain_queue(generator:&JsObject<AsyncGenerator>,context:&mutContext){
623+
pub(crate)fndrain_queue(
624+
generator:&JsObject<AsyncGenerator>,
625+
context:&mutContext,
626+
) ->JsResult<()>{
620627
// 1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
621628
assert_eq!(
622629
generator.borrow().data().state,
@@ -630,7 +637,7 @@ impl AsyncGenerator {
630637
generator.borrow_mut().data_mut().state =AsyncGeneratorState::Completed;
631638
generator.borrow_mut().data_mut().context =None;
632639
// b. Return unused.
633-
return;
640+
returnOk(());
634641
}
635642

636643
// 4. Let done be false.
@@ -651,7 +658,7 @@ impl AsyncGenerator {
651658
// c. If completion is a return completion, then
652659
CompletionRecord::Return(val) =>{
653660
// i. Perform AsyncGeneratorAwaitReturn(generator).
654-
Self::await_return(generator, val, context);
661+
Self::await_return(generator, val, context)?;
655662

656663
// ii. Set done to true.
657664
break;
@@ -663,7 +670,7 @@ impl AsyncGenerator {
663670
let completion = completion.consume().map(|_|JsValue::undefined());
664671

665672
// ii. Perform AsyncGeneratorCompleteStep(generator, completion, true).
666-
Self::complete_step(generator, completion,true,None, context);
673+
Self::complete_step(generator, completion,true,None, context)?;
667674

668675
// iii. If queue is empty, then
669676
if generator.borrow().data().queue.is_empty(){
@@ -678,5 +685,6 @@ impl AsyncGenerator {
678685
}
679686

680687
// 6. Return unused.
688+
Ok(())
681689
}
682690
}

‎core/engine/src/builtins/error/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub enum ErrorKind {
123123
/// This is used internally to convert between [`JsObject`] and
124124
/// [`JsNativeError`] correctly, but it can also be used to manually create `Error`
125125
/// objects. However, the recommended way to create them is to construct a
126-
/// `JsNativeError` first, then call [`JsNativeError::to_opaque`],
126+
/// `JsNativeError` first, then call [`JsNativeError::into_opaque`],
127127
/// which will assign its prototype, properties and kind automatically.
128128
///
129129
/// For a description of every error kind and its usage, see

‎core/engine/src/builtins/generator/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ impl Generator {
380380

381381
let(value, resume_kind) =match abrupt_completion{
382382
Ok(value) =>(value,GeneratorResumeKind::Return),
383-
Err(err) =>(err.to_opaque(context),GeneratorResumeKind::Throw),
383+
Err(err) =>(err.into_opaque(context)?,GeneratorResumeKind::Throw),
384384
};
385385

386386
let record = generator_context.resume(Some(value), resume_kind, context);

‎core/engine/src/builtins/iterable/async_from_sync_iterator.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl AsyncFromSyncIterator {
263263
&JsValue::undefined(),
264264
&[JsNativeError::typ()
265265
.with_message("sync iterator does not have a throw method")
266-
.to_opaque(context)
266+
.into_opaque(context)
267267
.into()],
268268
context,
269269
)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp