mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-23 02:26:35 +00:00
aws: improve error message logs
The `Display` and `Debug` trait for the AWS error messages are not very useful. - `Display` only prints the high level error, e.g.: "service error". - `Debug` prints all the fields in the error stack, resulting in hard to read messages with redudant or unnecessary information. E.g.: > ServiceError(ServiceError { source: BadRequestException(BadRequestException { > message: Some("1 validation error detected: Value 'test' at 'languageCode' > failed to satisfy constraint: Member must satisfy enum value set: [ar-AE, > zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH, > de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US, > fr-CA, en-GB]"), meta: ErrorMetadata { code: Some("BadRequestException"), > message: Some("1 validation error detected: Value 'test' at 'languageCode' > failed to satisfy constraint: Member must satisfy enum value set: [ar-AE, > zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH, > de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US, > fr-CA, en-GB]"), extras: Some({"aws_request_id": "1b8bbafd-5b71-4ba5-8676-28432381e6a9"}) } }), > raw: Response { status: StatusCode(400), headers: Headers { headers: > {"x-amzn-requestid": HeaderValue { _private: H0("1b8bbafd-5b71-4ba5-8676-28432381e6a9") }, > "x-amzn-errortype": HeaderValue { _private: > H0("BadRequestException:http://internal.amazon.com/coral/com.amazonaws.transcribe.streaming/") }, > "date": HeaderValue { _private: H0("Tue, 26 Mar 2024 17:41:31 GMT") }, > "content-type": HeaderValue { _private: H0("application/x-amz-json-1.1") }, > "content-length": HeaderValue { _private: H0("315") }} }, body: SdkBody { > inner: Once(Some(b"{\"Message\":\"1 validation error detected: Value 'test' > at 'languageCode' failed to satisfy constraint: Member must satisfy enum value > set: [ar-AE, zh-HK, en-US, ar-SA, zh-CN, fi-FI, pl-PL, no-NO, nl-NL, pt-PT, > es-ES, th-TH, de-DE, it-IT, fr-FR, ko-KR, hi-IN, en-AU, pt-BR, sv-SE, ja-JP, > ca-ES, es-US, fr-CA, en-GB]\"}")), retryable: true }, extensions: Extensions { > extensions_02x: Extensions, extensions_1x: Extensions } } }) This commit adopts the most informative and concise solution I could come up with to log AWS errors. With the above error case, this results in: > service error: Error { code: "BadRequestException", message: "1 validation > error detected: Value 'test' at 'languageCode' failed to satisfy constraint: > Member must satisfy enum value set: [ar-AE, zh-HK, en-US, ar-SA, zh-CN, fi-FI, > pl-PL, no-NO, nl-NL, pt-PT, es-ES, th-TH, de-DE, it-IT, fr-FR, ko-KR, hi-IN, > en-AU, pt-BR, sv-SE, ja-JP, ca-ES, es-US, fr-CA, en-GB]", > aws_request_id: "a40a32a8-7b0b-4228-a348-f8502087a9f0" } Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1521>
This commit is contained in:
parent
9f27bde36a
commit
a870d60621
7 changed files with 34 additions and 17 deletions
|
@ -276,10 +276,9 @@ impl S3HlsSink {
|
|||
gst::error!(
|
||||
CAT,
|
||||
imp: self,
|
||||
"Put object request for S3 key {} of data length {} failed with error {:?}",
|
||||
"Put object request for S3 key {} of data length {} failed with error {err}",
|
||||
s3_key,
|
||||
s3_data_len,
|
||||
err,
|
||||
);
|
||||
element_imp_error!(
|
||||
self,
|
||||
|
@ -320,9 +319,8 @@ impl S3HlsSink {
|
|||
gst::error!(
|
||||
CAT,
|
||||
imp: self,
|
||||
"Delete object request for S3 key {} failed with error {:?}",
|
||||
"Delete object request for S3 key {} failed with error {err}",
|
||||
s3_key,
|
||||
err
|
||||
);
|
||||
element_imp_error!(
|
||||
self,
|
||||
|
|
|
@ -14,6 +14,7 @@ use gst_base::subclass::prelude::*;
|
|||
|
||||
use aws_sdk_s3::{
|
||||
config::{self, retry::RetryConfig, Credentials, Region},
|
||||
error::ProvideErrorMetadata,
|
||||
operation::{
|
||||
abort_multipart_upload::builders::AbortMultipartUploadFluentBuilder,
|
||||
complete_multipart_upload::builders::CompleteMultipartUploadFluentBuilder,
|
||||
|
@ -265,7 +266,7 @@ impl S3Sink {
|
|||
self.flush_multipart_upload(state);
|
||||
Some(gst::error_msg!(
|
||||
gst::ResourceError::OpenWrite,
|
||||
["Failed to upload part: {}", err]
|
||||
["Failed to upload part: {err}: {}", err.meta()]
|
||||
))
|
||||
}
|
||||
WaitError::Cancelled => None,
|
||||
|
@ -407,7 +408,7 @@ impl S3Sink {
|
|||
WaitError::FutureError(err) => {
|
||||
gst::error_msg!(
|
||||
gst::ResourceError::Write,
|
||||
["Failed to abort multipart upload: {}.", err.to_string()]
|
||||
["Failed to abort multipart upload: {err}: {}", err.meta()]
|
||||
)
|
||||
}
|
||||
WaitError::Cancelled => {
|
||||
|
@ -431,7 +432,7 @@ impl S3Sink {
|
|||
.map_err(|err| match err {
|
||||
WaitError::FutureError(err) => gst::error_msg!(
|
||||
gst::ResourceError::Write,
|
||||
["Failed to complete multipart upload: {}.", err.to_string()]
|
||||
["Failed to complete multipart upload: {err}: {}", err.meta()]
|
||||
),
|
||||
WaitError::Cancelled => {
|
||||
gst::error_msg!(
|
||||
|
@ -512,7 +513,7 @@ impl S3Sink {
|
|||
.map_err(|err| match err {
|
||||
WaitError::FutureError(err) => gst::error_msg!(
|
||||
gst::ResourceError::OpenWrite,
|
||||
["Failed to create SDK config: {}", err]
|
||||
["Failed to create SDK config: {err}"]
|
||||
),
|
||||
WaitError::Cancelled => {
|
||||
gst::error_msg!(
|
||||
|
@ -541,7 +542,7 @@ impl S3Sink {
|
|||
|err| match err {
|
||||
WaitError::FutureError(err) => gst::error_msg!(
|
||||
gst::ResourceError::OpenWrite,
|
||||
["Failed to create multipart upload: {}", err]
|
||||
["Failed to create multipart upload: {err}: {}", err.meta()]
|
||||
),
|
||||
WaitError::Cancelled => {
|
||||
gst::error_msg!(
|
||||
|
|
|
@ -15,6 +15,7 @@ use gst_base::subclass::prelude::*;
|
|||
|
||||
use aws_sdk_s3::{
|
||||
config::{self, retry::RetryConfig, Credentials, Region},
|
||||
error::ProvideErrorMetadata,
|
||||
operation::put_object::builders::PutObjectFluentBuilder,
|
||||
primitives::ByteStream,
|
||||
Client,
|
||||
|
@ -202,7 +203,7 @@ impl S3PutObjectSink {
|
|||
s3utils::wait(&self.canceller, put_object_req_future).map_err(|err| match err {
|
||||
WaitError::FutureError(err) => Some(gst::error_msg!(
|
||||
gst::ResourceError::OpenWrite,
|
||||
["Failed to upload object: {}", err]
|
||||
["Failed to upload object: {err}: {}", err.meta()]
|
||||
)),
|
||||
WaitError::Cancelled => None,
|
||||
})?;
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::time::Duration;
|
|||
|
||||
use aws_sdk_s3::{
|
||||
config::{self, retry::RetryConfig, Credentials},
|
||||
error::ProvideErrorMetadata,
|
||||
Client,
|
||||
};
|
||||
|
||||
|
@ -184,7 +185,7 @@ impl S3Src {
|
|||
s3utils::wait(&self.canceller, head_object_future).map_err(|err| match err {
|
||||
WaitError::FutureError(err) => gst::error_msg!(
|
||||
gst::ResourceError::NotFound,
|
||||
["Failed to get HEAD object: {:?}", err]
|
||||
["Failed to get HEAD object: {err}: {}", err.meta()]
|
||||
),
|
||||
WaitError::Cancelled => {
|
||||
gst::error_msg!(
|
||||
|
@ -243,7 +244,7 @@ impl S3Src {
|
|||
s3utils::wait(&self.canceller, get_object_future).map_err(|err| match err {
|
||||
WaitError::FutureError(err) => Some(gst::error_msg!(
|
||||
gst::ResourceError::Read,
|
||||
["Could not read: {}", err]
|
||||
["Could not read: {err}: {}", err.meta()]
|
||||
)),
|
||||
WaitError::Cancelled => None,
|
||||
})?;
|
||||
|
@ -253,7 +254,7 @@ impl S3Src {
|
|||
s3utils::wait_stream(&self.canceller, &mut output.body).map_err(|err| match err {
|
||||
WaitError::FutureError(err) => Some(gst::error_msg!(
|
||||
gst::ResourceError::Read,
|
||||
["Could not read: {}", err]
|
||||
["Could not read: {err}"]
|
||||
)),
|
||||
WaitError::Cancelled => None,
|
||||
})
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
use aws_config::meta::region::RegionProviderChain;
|
||||
use aws_sdk_s3::{
|
||||
config::{timeout::TimeoutConfig, Credentials, Region},
|
||||
error::ProvideErrorMetadata,
|
||||
primitives::{ByteStream, ByteStreamError},
|
||||
};
|
||||
use aws_types::sdk_config::SdkConfig;
|
||||
|
@ -16,6 +17,7 @@ use aws_types::sdk_config::SdkConfig;
|
|||
use bytes::{buf::BufMut, Bytes, BytesMut};
|
||||
use futures::{future, Future};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::fmt;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
use tokio::runtime;
|
||||
|
@ -40,6 +42,15 @@ pub enum WaitError<E> {
|
|||
FutureError(E),
|
||||
}
|
||||
|
||||
impl<E: ProvideErrorMetadata + std::error::Error> fmt::Display for WaitError<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
WaitError::Cancelled => f.write_str("Cancelled"),
|
||||
WaitError::FutureError(err) => write!(f, "{err}: {}", err.meta()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait<F, T, E>(
|
||||
canceller: &Mutex<Option<future::AbortHandle>>,
|
||||
future: F,
|
||||
|
|
|
@ -11,6 +11,7 @@ use gst::subclass::prelude::*;
|
|||
use gst::{glib, prelude::*};
|
||||
|
||||
use aws_sdk_transcribestreaming as aws_transcribe;
|
||||
use aws_sdk_transcribestreaming::error::ProvideErrorMetadata;
|
||||
use aws_sdk_transcribestreaming::types;
|
||||
|
||||
use futures::channel::mpsc;
|
||||
|
@ -165,7 +166,7 @@ impl TranscriberStream {
|
|||
.send()
|
||||
.await
|
||||
.map_err(|err| {
|
||||
let err = format!("Transcribe ws init error: {err}");
|
||||
let err = format!("Transcribe ws init error: {err}: {}", err.meta());
|
||||
gst::error!(CAT, imp: imp, "{err}");
|
||||
gst::error_msg!(gst::LibraryError::Init, ["{err}"])
|
||||
})?;
|
||||
|
@ -187,7 +188,7 @@ impl TranscriberStream {
|
|||
.recv()
|
||||
.await
|
||||
.map_err(|err| {
|
||||
let err = format!("Transcribe ws stream error: {err}");
|
||||
let err = format!("Transcribe ws stream error: {err}: {}", err.meta());
|
||||
gst::error!(CAT, imp: self.imp, "{err}");
|
||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||
})?;
|
||||
|
|
|
@ -10,6 +10,7 @@ use gst::glib;
|
|||
use gst::subclass::prelude::*;
|
||||
|
||||
use aws_sdk_translate as aws_translate;
|
||||
use aws_sdk_translate::error::ProvideErrorMetadata;
|
||||
|
||||
use futures::channel::mpsc;
|
||||
use futures::prelude::*;
|
||||
|
@ -78,7 +79,10 @@ impl TranslateLoop {
|
|||
|
||||
pub async fn check_language(&self) -> Result<(), gst::ErrorMessage> {
|
||||
let language_list = self.client.list_languages().send().await.map_err(|err| {
|
||||
let err = format!("Failed to call list_languages service: {err}");
|
||||
let err = format!(
|
||||
"Failed to call list_languages service: {err}: {}",
|
||||
err.meta()
|
||||
);
|
||||
gst::info!(CAT, imp: self.pad, "{err}");
|
||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||
})?;
|
||||
|
@ -143,7 +147,7 @@ impl TranslateLoop {
|
|||
.send()
|
||||
.await
|
||||
.map_err(|err| {
|
||||
let err = format!("Failed to call translation service: {err}");
|
||||
let err = format!("Failed to call translation service: {err}: {}", err.meta());
|
||||
gst::info!(CAT, imp: self.pad, "{err}");
|
||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||
})?
|
||||
|
|
Loading…
Reference in a new issue