core: Replaced tag_utils Error with an actual Error enum

This commit is contained in:
= 2022-08-20 22:36:51 +02:00 committed by Nathan Adams
parent 67eb34fbc5
commit 620820be9e
4 changed files with 80 additions and 48 deletions

View File

@ -267,7 +267,7 @@ impl<'gc> Avm2<'gc> {
domain: Domain<'gc>,
reader: &mut SwfStream<'_>,
tag_len: usize,
) -> Result<(), Error> {
) -> Result<(), crate::tag_utils::Error> {
let start = reader.as_slice();
// Queue the actions.
// TODO: The tag reader parses the entire ABC file, instead of just
@ -282,7 +282,8 @@ impl<'gc> Avm2<'gc> {
let slice = swf.resize_to_reader(reader, tag_len - num_read);
if !slice.is_empty() {
Avm2::load_abc(slice, &name, is_lazy_initialize, context, domain)?;
Avm2::load_abc(slice, &name, is_lazy_initialize, context, domain)
.map_err(|e| crate::tag_utils::Error::InvalidABC(e.to_string()))?;
}
Ok(())

View File

@ -34,7 +34,7 @@ use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
use crate::font::Font;
use crate::prelude::*;
use crate::string::{AvmString, WStr, WString};
use crate::tag_utils::{self, DecodeResult, SwfMovie, SwfSlice, SwfStream};
use crate::tag_utils::{self, DecodeResult, Error, SwfMovie, SwfSlice, SwfStream};
use crate::vminterface::{AvmObject, Instantiator};
use gc_arena::{Collect, Gc, GcCell, MutationContext};
use smallvec::SmallVec;
@ -589,9 +589,7 @@ impl<'gc> MovieClip<'gc> {
context: &mut UpdateContext<'_, 'gc, '_>,
reader: &mut SwfStream<'_>,
) -> DecodeResult {
let movie = self
.movie()
.ok_or("Attempted to set symbol classes on movie without any")?;
let movie = self.movie().ok_or(Error::NoSymbolClasses)?;
let mut activation = Avm2Activation::from_nothing(context.reborrow());
let num_symbols = reader.read_u16()?;
@ -2633,11 +2631,7 @@ impl<'gc, 'a> MovieClipData<'gc> {
Ok(())
}
_ => Err(format!(
"Attempted to preload video frames into non-video character {}",
vframe.stream_id
)
.into()),
_ => Err(Error::PreloadVideoIntoInvalidCharacter(vframe.stream_id)),
}
}

View File

@ -134,6 +134,11 @@ pub enum Error {
// the GC arena). We're losing info here. How do we fix that?
#[error("Error running avm1 script: {0}")]
Avm1Error(String),
// TODO: We can't support lifetimes on this error object yet (or we'll need some backends inside
// the GC arena). We're losing info here. How do we fix that?
#[error("Error running avm2 script: {0}")]
Avm2Error(String),
}
impl From<crate::avm1::error::Error<'_>> for Error {
@ -579,10 +584,8 @@ impl<'gc> Loader<'gc> {
event_handler
{
let mut loader = loader_info
.get_property(
&Multiname::public("loader"),
&mut activation,
)?
.get_property(&Multiname::public("loader"), &mut activation)
.map_err(|e| Error::Avm2Error(e.to_string()))?
.as_object()
.unwrap()
.as_display_object()
@ -879,7 +882,8 @@ impl<'gc> Loader<'gc> {
// FIXME - Match the exact error message generated by Flash
let io_error_evt_cls = activation.avm2().classes().ioerrorevent;
let io_error_evt = io_error_evt_cls.construct(
let io_error_evt = io_error_evt_cls
.construct(
&mut activation,
&[
"ioError".into(),
@ -888,7 +892,8 @@ impl<'gc> Loader<'gc> {
"Error #2032: Stream Error".into(),
2032.into(),
],
)?;
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, target) {
log::error!(
@ -990,7 +995,11 @@ impl<'gc> Loader<'gc> {
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
let mut activation = Avm2Activation::from_nothing(uc.reborrow());
let progress_evt = activation.avm2().classes().progressevent.construct(
let progress_evt = activation
.avm2()
.classes()
.progressevent
.construct(
&mut activation,
&[
"progress".into(),
@ -999,7 +1008,8 @@ impl<'gc> Loader<'gc> {
cur_len.into(),
total_len.into(),
],
)?;
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, progress_evt, loader_info) {
log::error!(
@ -1101,7 +1111,8 @@ impl<'gc> Loader<'gc> {
// FIXME - Match the exact error message generated by Flash
let io_error_evt_cls = activation.avm2().classes().ioerrorevent;
let io_error_evt = io_error_evt_cls.construct(
let io_error_evt = io_error_evt_cls
.construct(
&mut activation,
&[
"ioError".into(),
@ -1110,7 +1121,8 @@ impl<'gc> Loader<'gc> {
"Movie loader error".into(),
0.into(),
],
)?;
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, loader_info) {
log::error!(

View File

@ -1,8 +1,33 @@
use gc_arena::Collect;
use std::sync::Arc;
use swf::{Fixed8, HeaderExt, Rectangle, TagCode, Twips};
use swf::{CharacterId, Fixed8, HeaderExt, Rectangle, TagCode, Twips};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Couldn't read SWF")]
InvalidSwf(#[from] swf::error::Error),
#[error("Couldn't register bitmap")]
InvalidBitmap(#[from] ruffle_render::error::Error),
#[error("Attempted to set symbol classes on movie without any")]
NoSymbolClasses,
#[error("Attempted to preload video frames into non-video character {0}")]
PreloadVideoIntoInvalidCharacter(CharacterId),
#[error("IO Error")]
IOError(#[from] std::io::Error),
#[error("Invalid SWF url")]
InvalidSwfUrl,
// TODO: Replace avm2 errors with something more substantial
#[error("Invalid ABC: {0}")]
InvalidABC(String),
}
pub type Error = Box<dyn std::error::Error>;
pub type DecodeResult = Result<(), Error>;
pub type SwfStream<'a> = swf::read::Reader<'a>;
@ -57,7 +82,7 @@ impl SwfMovie {
let data = std::fs::read(&path)?;
let abs_path = path.as_ref().canonicalize()?;
let url = url::Url::from_file_path(abs_path).map_err(|()| "Invalid SWF URL")?;
let url = url::Url::from_file_path(abs_path).map_err(|()| Error::InvalidSwfUrl)?;
Self::from_data(&data, Some(url.into()), loader_url)
}