@@ -12,6 +12,7 @@ mod paginate;
1212pub use paginate:: * ;
1313
1414use crate :: { serenity:: CreateAllowedMentions , serenity_prelude as serenity, CreateReply } ;
15+ use std:: fmt:: { self , Display } ;
1516
1617/// An error handler that logs errors either via the [`tracing`] crate or via a Discord message. Set
1718/// up a logger like tracing subscriber
@@ -29,20 +30,20 @@ use crate::{serenity::CreateAllowedMentions, serenity_prelude as serenity, Creat
2930/// }
3031/// # };
3132/// ```
32- pub async fn on_error < U , E : std:: fmt :: Display + std :: fmt :: Debug > (
33+ pub async fn on_error < U , E : Into < Box < dyn std:: error :: Error + Send + Sync > > > (
3334 error : crate :: FrameworkError < ' _ , U , E > ,
3435) -> Result < ( ) , serenity:: Error > {
3536 match error {
3637 crate :: FrameworkError :: Setup { error, .. } => {
37- eprintln ! ( "Error in user data setup: {}" , error) ;
38+ eprintln ! ( "Error in user data setup: {}" , display_error ( error) ) ;
3839 }
3940 crate :: FrameworkError :: EventHandler { error, event, .. } => tracing:: error!(
4041 "User event event handler encountered an error on {} event: {}" ,
4142 event. snake_case_name( ) ,
42- error
43+ display_error ( error)
4344 ) ,
4445 crate :: FrameworkError :: Command { ctx, error } => {
45- let error = error. to_string ( ) ;
46+ let error = display_error ( error) . to_string ( ) ;
4647 eprintln ! ( "An error occured in a command: {}" , error) ;
4748
4849 let mentions = CreateAllowedMentions :: new ( )
@@ -116,14 +117,19 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
116117 description,
117118 ) ;
118119 }
119- crate :: FrameworkError :: CommandCheckFailed { ctx, error } => {
120- tracing:: error!(
121- "A command check failed in command {} for user {}: {:? }" ,
120+ crate :: FrameworkError :: CommandCheckFailed { ctx, error } => match error {
121+ Some ( error ) => tracing:: error!(
122+ "A command check failed in command {} for user {}: {}" ,
122123 ctx. command( ) . name,
123124 ctx. author( ) . name,
124- error,
125- ) ;
126- }
125+ display_error( error) ,
126+ ) ,
127+ None => tracing:: error!(
128+ "A command check failed in command {} for user {}" ,
129+ ctx. command( ) . name,
130+ ctx. author( ) . name,
131+ ) ,
132+ } ,
127133 crate :: FrameworkError :: CooldownHit {
128134 remaining_cooldown,
129135 ctx,
@@ -195,7 +201,7 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
195201 tracing:: error!(
196202 "Dynamic prefix failed for message {:?}: {}" ,
197203 msg. content,
198- error
204+ display_error ( error)
199205 ) ;
200206 }
201207 crate :: FrameworkError :: UnknownCommand {
@@ -213,7 +219,10 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
213219 tracing:: warn!( "received unknown interaction \" {}\" " , interaction. data. name) ;
214220 }
215221 crate :: FrameworkError :: NonCommandMessage { error, .. } => {
216- tracing:: warn!( "error in non-command message handler: {}" , error) ;
222+ tracing:: warn!(
223+ "error in non-command message handler: {}" ,
224+ display_error( error)
225+ ) ;
217226 }
218227 crate :: FrameworkError :: __NonExhaustive( unreachable) => match unreachable { } ,
219228 }
@@ -328,3 +337,26 @@ pub async fn servers<U, E>(ctx: crate::Context<'_, U, E>) -> Result<(), serenity
328337 ctx. send ( reply) . await ?;
329338 Ok ( ( ) )
330339}
340+
341+ /// Helper function to display an `impl Into<Box<dyn std::error::Error>>` and its chain of causes.
342+ fn display_error ( e : impl Into < Box < dyn std:: error:: Error + Send + Sync > > ) -> impl Display {
343+ struct DisplayError ( Box < dyn std:: error:: Error + Send + Sync > ) ;
344+
345+ impl Display for DisplayError {
346+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
347+ let mut e: & ( dyn std:: error:: Error + ' static ) = & * self . 0 ;
348+
349+ Display :: fmt ( e, f) ?;
350+
351+ while let Some ( new_e) = e. source ( ) {
352+ f. write_str ( ": " ) ?;
353+ Display :: fmt ( new_e, f) ?;
354+ e = new_e;
355+ }
356+
357+ Ok ( ( ) )
358+ }
359+ }
360+
361+ DisplayError ( e. into ( ) )
362+ }
0 commit comments