From a77995f1c8fe7d221ce3afef8bd8b92342e42321 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 3 Jan 2024 15:34:47 +0100 Subject: [PATCH] Pass on formatted error messages (#416) This will improve diagnostics when things go wrong as the text of the error will be included in the Servo media error as well. --- backends/gstreamer/audio_decoder.rs | 28 +++++++++++------------ backends/gstreamer/audio_sink.rs | 22 +++++++++--------- backends/gstreamer/audio_stream_reader.rs | 14 ++++++------ backends/gstreamer/player.rs | 8 +++---- backends/gstreamer/render-android/lib.rs | 2 +- backends/gstreamer/render-unix/lib.rs | 2 +- backends/gstreamer/render.rs | 2 +- backends/gstreamer/webrtc.rs | 2 +- examples/player/app.rs | 18 +++++++-------- 9 files changed, 49 insertions(+), 49 deletions(-) diff --git a/backends/gstreamer/audio_decoder.rs b/backends/gstreamer/audio_decoder.rs index cabf4fe1..fa12e52b 100644 --- a/backends/gstreamer/audio_decoder.rs +++ b/backends/gstreamer/audio_decoder.rs @@ -146,26 +146,26 @@ impl AudioDecoder for GStreamerAudioDecoder { let insert_deinterleave = || -> Result<(), AudioDecoderError> { let convert = gst::ElementFactory::make("audioconvert") .build() - .map_err(|_| { - AudioDecoderError::Backend("audioconvert creation failed".to_owned()) + .map_err(|error| { + AudioDecoderError::Backend(format!("audioconvert creation failed: {error:?}")) })?; let resample = gst::ElementFactory::make("audioresample") .build() - .map_err(|_| { - AudioDecoderError::Backend("audioresample creation failed".to_owned()) + .map_err(|error| { + AudioDecoderError::Backend(format!("audioresample creation failed: {error:?}")) })?; let filter = gst::ElementFactory::make("capsfilter") .build() - .map_err(|_| { - AudioDecoderError::Backend("capsfilter creation failed".to_owned()) + .map_err(|error| { + AudioDecoderError::Backend(format!("capsfilter creation failed: {error:?}")) })?; let deinterleave = gst::ElementFactory::make("deinterleave") .name("deinterleave") .property("keep-positions", true) .build() - .map_err(|_| { - AudioDecoderError::Backend("deinterleave creation failed".to_owned()) + .map_err(|error| { + AudioDecoderError::Backend(format!("deinterleave creation failed: {error:?}")) })?; let pipeline_ = pipeline.downgrade(); @@ -187,11 +187,11 @@ impl AudioDecoder for GStreamerAudioDecoder { } }; let insert_sink = || -> Result<(), AudioDecoderError> { - let queue = gst::ElementFactory::make("queue").build().map_err(|_| { - AudioDecoderError::Backend("queue creation failed".to_owned()) + let queue = gst::ElementFactory::make("queue").build().map_err(|error| { + AudioDecoderError::Backend(format!("queue creation failed: {error:?}")) })?; - let sink = gst::ElementFactory::make("appsink").build().map_err(|_| { - AudioDecoderError::Backend("appsink creation failed".to_owned()) + let sink = gst::ElementFactory::make("appsink").build().map_err(|error| { + AudioDecoderError::Backend(format!("appsink creation failed: {error:?}")) })?; let appsink = sink.clone().dynamic_cast::().unwrap(); sink.set_property("sync", false); @@ -278,10 +278,10 @@ impl AudioDecoder for GStreamerAudioDecoder { } let audio_info = audio_info_builder .build() - .map_err(|_| AudioDecoderError::Backend("AudioInfo failed".to_owned()))?; + .map_err(|error| AudioDecoderError::Backend(format!("AudioInfo failed: {error:?}")))?; let caps = audio_info .to_caps() - .map_err(|_| AudioDecoderError::Backend("AudioInfo failed".to_owned()))?; + .map_err(|error| AudioDecoderError::Backend(format!("AudioInfo failed: {error:?}")))?; filter.set_property("caps", caps); let elements = &[&convert, &resample, &filter, &deinterleave]; diff --git a/backends/gstreamer/audio_sink.rs b/backends/gstreamer/audio_sink.rs index 47f5e3de..48c3b3a3 100644 --- a/backends/gstreamer/audio_sink.rs +++ b/backends/gstreamer/audio_sink.rs @@ -28,11 +28,11 @@ impl GStreamerAudioSink { if let Some(category) = gst::DebugCategory::get("openslessink") { category.set_threshold(gst::DebugLevel::Trace); } - gst::init().map_err(|_| AudioSinkError::Backend("GStreamer init failed".to_owned()))?; + gst::init().map_err(|error| AudioSinkError::Backend(format!("GStreamer init failed: {error:?}")))?; let appsrc = gst::ElementFactory::make("appsrc") .build() - .map_err(|_| AudioSinkError::Backend("appsrc creation failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("appsrc creation failed: {error:?}")))?; let appsrc = appsrc.downcast::().unwrap(); Ok(Self { @@ -53,7 +53,7 @@ impl GStreamerAudioSink { channels.into(), ) .build() - .map_err(|_| AudioSinkError::Backend("AudioInfo failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("AudioInfo failed: {error:?}")))?; self.appsrc.set_caps(audio_info.to_caps().ok().as_ref()); *self.audio_info.borrow_mut() = Some(audio_info); Ok(()) @@ -101,18 +101,18 @@ impl AudioSink for GStreamerAudioSink { let appsrc = self.appsrc.as_ref().clone().upcast(); let resample = gst::ElementFactory::make("audioresample") .build() - .map_err(|_| AudioSinkError::Backend("audioresample creation failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("audioresample creation failed: {error:?}")))?; let convert = gst::ElementFactory::make("audioconvert") .build() - .map_err(|_| AudioSinkError::Backend("audioconvert creation failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("audioconvert creation failed: {error:?}")))?; let sink = gst::ElementFactory::make("autoaudiosink") .build() - .map_err(|_| AudioSinkError::Backend("autoaudiosink creation failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("autoaudiosink creation failed: {error:?}")))?; self.pipeline .add_many(&[&appsrc, &resample, &convert, &sink]) - .map_err(|e| AudioSinkError::Backend(e.to_string()))?; + .map_err(|error| AudioSinkError::Backend(error.to_string()))?; gst::Element::link_many(&[&appsrc, &resample, &convert, &sink]) - .map_err(|e| AudioSinkError::Backend(e.to_string()))?; + .map_err(|error| AudioSinkError::Backend(error.to_string()))?; Ok(()) } @@ -132,7 +132,7 @@ impl AudioSink for GStreamerAudioSink { let appsrc = self.appsrc.as_ref().clone().upcast(); let convert = gst::ElementFactory::make("audioconvert") .build() - .map_err(|_| AudioSinkError::Backend("audioconvert creation failed".to_owned()))?; + .map_err(|error| AudioSinkError::Backend(format!("audioconvert creation failed: {error:?}")))?; let sink = socket .as_any() .downcast_ref::() @@ -142,9 +142,9 @@ impl AudioSink for GStreamerAudioSink { self.pipeline .add_many(&[&appsrc, &convert, &sink]) - .map_err(|e| AudioSinkError::Backend(e.to_string()))?; + .map_err(|error| AudioSinkError::Backend(error.to_string()))?; gst::Element::link_many(&[&appsrc, &convert, &sink]) - .map_err(|e| AudioSinkError::Backend(e.to_string()))?; + .map_err(|error| AudioSinkError::Backend(error.to_string()))?; Ok(()) } diff --git a/backends/gstreamer/audio_stream_reader.rs b/backends/gstreamer/audio_stream_reader.rs index d69e58df..a30aaf56 100644 --- a/backends/gstreamer/audio_stream_reader.rs +++ b/backends/gstreamer/audio_stream_reader.rs @@ -36,15 +36,15 @@ impl GStreamerAudioStreamReader { let capsfilter0 = gst::ElementFactory::make("capsfilter") .property("caps", caps) .build() - .map_err(|_| "capsfilter creation failed".to_owned())?; + .map_err(|error| format!("capsfilter creation failed: {error:?}"))?; let split = gst::ElementFactory::make("audiobuffersplit") .property("output-buffer-duration", time_per_block) .build() - .map_err(|_| "audiobuffersplit creation failed".to_owned())?; + .map_err(|error| format!("audiobuffersplit creation failed: {error:?}"))?; let convert = gst::ElementFactory::make("audioconvert") .build() - .map_err(|_| "audioconvert creation failed".to_owned())?; + .map_err(|error| format!("audioconvert creation failed: {error:?}"))?; let caps = gst_audio::AudioCapsBuilder::new() .layout(gst_audio::AudioLayout::NonInterleaved) .format(AUDIO_FORMAT_F32) @@ -53,19 +53,19 @@ impl GStreamerAudioStreamReader { let capsfilter = gst::ElementFactory::make("capsfilter") .property("caps", caps) .build() - .map_err(|_| "capsfilter creation failed".to_owned())?; + .map_err(|error| format!("capsfilter creation failed: {error:?}"))?; let sink = gst::ElementFactory::make("appsink") .property("sync", false) .build() - .map_err(|_| "appsink creation failed".to_owned())?; + .map_err(|error| format!("appsink creation failed: {error:?}"))?; let appsink = sink.clone().dynamic_cast::().unwrap(); let elements = [&element, &capsfilter0, &split, &convert, &capsfilter, &sink]; pipeline .add_many(&elements[1..]) - .map_err(|_| "pipeline adding failed".to_owned())?; - gst::Element::link_many(&elements).map_err(|_| "element linking failed".to_owned())?; + .map_err(|error| format!("pipeline adding failed: {error:?}"))?; + gst::Element::link_many(&elements).map_err(|error| format!("element linking failed: {error:?}"))?; for e in &elements { e.sync_state_with_parent().map_err(|e| e.to_string())?; } diff --git a/backends/gstreamer/player.rs b/backends/gstreamer/player.rs index 8e81d476..8f429062 100644 --- a/backends/gstreamer/player.rs +++ b/backends/gstreamer/player.rs @@ -461,7 +461,7 @@ impl GStreamerPlayer { if let Some(ref audio_renderer) = self.audio_renderer { let audio_sink = gst::ElementFactory::make("appsink") .build() - .map_err(|_| PlayerError::Backend("appsink creation failed".to_owned()))?; + .map_err(|error| PlayerError::Backend(format!("appsink creation failed: {error:?}")))?; pipeline.set_property("audio-sink", &audio_sink); @@ -506,14 +506,14 @@ impl GStreamerPlayer { // https://github.com/servo/servo/issues/22010#issuecomment-432599657 let uri = match self.stream_type { StreamType::Stream => { - register_servo_media_stream_src().map_err(|_| { - PlayerError::Backend("servomediastreamsrc registration error".to_owned()) + register_servo_media_stream_src().map_err(|error| { + PlayerError::Backend(format!("servomediastreamsrc registration error: {error:?}")) })?; "mediastream://".to_value() } StreamType::Seekable => { register_servo_src() - .map_err(|_| PlayerError::Backend("servosrc registration error".to_owned()))?; + .map_err(|error| PlayerError::Backend(format!("servosrc registration error: {error:?}")))?; "servosrc://".to_value() } }; diff --git a/backends/gstreamer/render-android/lib.rs b/backends/gstreamer/render-android/lib.rs index 3f7189e8..9e62b679 100644 --- a/backends/gstreamer/render-android/lib.rs +++ b/backends/gstreamer/render-android/lib.rs @@ -192,7 +192,7 @@ impl Render for RenderAndroid { .name("servo-media-vsink") .property("sink", &appsink) .build() - .map_err(|_| PlayerError::Backend("glupload creation failed".to_owned()))?; + .map_err(|error| PlayerError::Backend(format!("glupload creation failed: {error:?}")))?; pipeline.set_property("video-sink", &vsinkbin); diff --git a/backends/gstreamer/render-unix/lib.rs b/backends/gstreamer/render-unix/lib.rs index e70ca549..92959dd5 100644 --- a/backends/gstreamer/render-unix/lib.rs +++ b/backends/gstreamer/render-unix/lib.rs @@ -218,7 +218,7 @@ impl Render for RenderUnix { let vsinkbin = gst::ElementFactory::make("glsinkbin") .name("servo-media-vsink") .build() - .map_err(|_| PlayerError::Backend("glupload creation failed".to_owned()))?; + .map_err(|error| PlayerError::Backend(format!("glupload creation failed: {error:?}")))?; let caps = gst::Caps::builder("video/x-raw") .features([gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY]) diff --git a/backends/gstreamer/render.rs b/backends/gstreamer/render.rs index 67cb31f3..ce426fdb 100644 --- a/backends/gstreamer/render.rs +++ b/backends/gstreamer/render.rs @@ -130,7 +130,7 @@ impl GStreamerRender { ) -> Result { let appsink = gst::ElementFactory::make("appsink") .build() - .map_err(|_| PlayerError::Backend("appsink creation failed".to_owned()))? + .map_err(|error| PlayerError::Backend(format!("appsink creation failed: {error:?}")))? .downcast::() .unwrap(); diff --git a/backends/gstreamer/webrtc.rs b/backends/gstreamer/webrtc.rs index 77bb5987..988bc16a 100644 --- a/backends/gstreamer/webrtc.rs +++ b/backends/gstreamer/webrtc.rs @@ -650,7 +650,7 @@ pub fn construct( let webrtc = gst::ElementFactory::make("webrtcbin") .name("sendrecv") .build() - .map_err(|_| "webrtcbin element not found")?; + .map_err(|error| format!("webrtcbin element not found: {error:?}"))?; let mut controller = GStreamerWebRtcController { webrtc, pipeline, diff --git a/examples/player/app.rs b/examples/player/app.rs index cfe17fba..d0b9bd87 100644 --- a/examples/player/app.rs +++ b/examples/player/app.rs @@ -185,7 +185,7 @@ impl App { // player let (player_event_sender, player_event_receiver) = ipc::channel::()?; let servo_media = - ServoMedia::get().map_err(|_| MiscError("Failed to get media backend"))?; + ServoMedia::get().map_err(|error| MiscError(format!("Failed to get media backend: {error:?}").as_str()))?; let frame_renderer = if !opts.no_video { Some(Arc::new(Mutex::new(MediaFrameRenderer::new( @@ -219,7 +219,7 @@ impl App { .lock() .unwrap() .set_input_size(metadata.len()) - .map_err(|_| MiscError("Failed to set media input size"))?; + .map_err(|error| MiscError(format!("Failed to set media input size: {error:?}").as_str()))?; Ok(App { events_loop, @@ -283,7 +283,7 @@ pub fn main_loop(mut app: App) -> Result Result { @@ -346,14 +346,14 @@ pub fn main_loop(mut app: App) -> Result { player .lock() .unwrap() .play() - .map_err(|_| MiscError("Failed to start player"))?; + .map_err(|error| MiscError(format!("Failed to start player: {error:?}").as_str()))?; } PlayerCmd::Seek(time) => { let time = playerstate.pos + time; @@ -365,7 +365,7 @@ pub fn main_loop(mut app: App) -> Result { playerstate.mute = !playerstate.mute; @@ -373,7 +373,7 @@ pub fn main_loop(mut app: App) -> Result (), } @@ -419,7 +419,7 @@ pub fn main_loop(mut app: App) -> Result