Make spawned futures falliable, and report those errors.

This commit is contained in:
David Wendt 2019-11-14 14:52:13 -05:00
parent 5ce499d11e
commit f4e4171ebe
4 changed files with 26 additions and 9 deletions

View File

@ -1638,7 +1638,7 @@ impl<'gc> Avm1<'gc> {
let slot = self.forcibly_root_object(context.layers[level_id].object().as_object()?); let slot = self.forcibly_root_object(context.layers[level_id].object().as_object()?);
context.navigator.spawn_future(Box::pin(async move { context.navigator.spawn_future(Box::pin(async move {
let data = fetch.await.unwrap(); let data = fetch.await?;
let movie = Arc::new(SwfMovie::from_data(&data)); let movie = Arc::new(SwfMovie::from_data(&data));
player.lock().unwrap().update(|avm, uc| { player.lock().unwrap().update(|avm, uc| {
@ -1660,6 +1660,8 @@ impl<'gc> Avm1<'gc> {
crate::character::Character::MorphShape(morph_shape), crate::character::Character::MorphShape(morph_shape),
); );
} }
Ok(())
}) })
})); }));
@ -1713,14 +1715,16 @@ impl<'gc> Avm1<'gc> {
let slot = self.forcibly_root_object(target_obj); let slot = self.forcibly_root_object(target_obj);
context.navigator.spawn_future(Box::pin(async move { context.navigator.spawn_future(Box::pin(async move {
let data = fetch.await.unwrap(); let data = fetch.await?;
player.lock().unwrap().update(|avm, uc| { player.lock().unwrap().update(|avm, uc| {
let that = avm.unroot_object(slot); let that = avm.unroot_object(slot);
for (k, v) in form_urlencoded::parse(&data) { for (k, v) in form_urlencoded::parse(&data) {
that.set(&k, v.into_owned().into(), avm, uc); that.set(&k, v.into_owned().into(), avm, uc)?;
} }
Ok(())
}) })
})); }));
} }
@ -1733,7 +1737,7 @@ impl<'gc> Avm1<'gc> {
let slot = self.forcibly_root_object(clip_target.object().as_object()?); let slot = self.forcibly_root_object(clip_target.object().as_object()?);
context.navigator.spawn_future(Box::pin(async move { context.navigator.spawn_future(Box::pin(async move {
let data = fetch.await.unwrap(); let data = fetch.await?;
let movie = Arc::new(SwfMovie::from_data(&data)); let movie = Arc::new(SwfMovie::from_data(&data));
player.lock().unwrap().update(|avm, uc| { player.lock().unwrap().update(|avm, uc| {
@ -1755,6 +1759,8 @@ impl<'gc> Avm1<'gc> {
crate::character::Character::MorphShape(morph_shape), crate::character::Character::MorphShape(morph_shape),
); );
} }
Ok(())
}) })
})) }))
} }

View File

@ -69,7 +69,7 @@ pub trait NavigatorBackend {
/// ///
/// TODO: For some reason, `wasm_bindgen_futures` wants unpinnable futures. /// TODO: For some reason, `wasm_bindgen_futures` wants unpinnable futures.
/// This seems highly limiting. /// This seems highly limiting.
fn spawn_future(&mut self, future: Pin<Box<dyn Future<Output = ()> + 'static>>); fn spawn_future(&mut self, future: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>);
} }
/// A null implementation for platforms that do not live in a web browser. /// A null implementation for platforms that do not live in a web browser.
@ -100,5 +100,9 @@ impl NavigatorBackend for NullNavigatorBackend {
Box::pin(async { Err("Fetch IO not implemented".into()) }) Box::pin(async { Err("Fetch IO not implemented".into()) })
} }
fn spawn_future(&mut self, _future: Pin<Box<dyn Future<Output = ()> + 'static>>) {} fn spawn_future(
&mut self,
_future: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>,
) {
}
} }

View File

@ -67,7 +67,10 @@ impl NavigatorBackend for ExternalNavigatorBackend {
Box::pin(async { Err("Fetch not implemented on desktop!".into()) }) Box::pin(async { Err("Fetch not implemented on desktop!".into()) })
} }
fn spawn_future(&mut self, _future: Pin<Box<dyn Future<Output = ()> + 'static>>) { fn spawn_future(
&mut self,
_future: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>,
) {
unimplemented!(); unimplemented!();
} }
} }

View File

@ -99,7 +99,11 @@ impl NavigatorBackend for WebNavigatorBackend {
}) })
} }
fn spawn_future(&mut self, future: Pin<Box<dyn Future<Output = ()> + 'static>>) { fn spawn_future(&mut self, future: Pin<Box<dyn Future<Output = Result<(), Error>> + 'static>>) {
spawn_local(future) spawn_local(async move {
if let Err(e) = future.await {
log::error!("Asynchronous error occured: {}", e);
}
})
} }
} }