@@ -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 ( )
@@ -118,14 +119,19 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
118119 description,
119120 ) ;
120121 }
121- crate :: FrameworkError :: CommandCheckFailed { ctx, error } => {
122- tracing:: error!(
123- "A command check failed in command {} for user {}: {:? }" ,
122+ crate :: FrameworkError :: CommandCheckFailed { ctx, error } => match error {
123+ Some ( error ) => tracing:: error!(
124+ "A command check failed in command {} for user {}: {}" ,
124125 ctx. command( ) . name,
125126 ctx. author( ) . name,
126- error,
127- ) ;
128- }
127+ display_error( error) ,
128+ ) ,
129+ None => tracing:: error!(
130+ "A command check failed in command {} for user {}" ,
131+ ctx. command( ) . name,
132+ ctx. author( ) . name,
133+ ) ,
134+ } ,
129135 crate :: FrameworkError :: CooldownHit {
130136 remaining_cooldown,
131137 ctx,
@@ -197,7 +203,7 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
197203 tracing:: error!(
198204 "Dynamic prefix failed for message {:?}: {}" ,
199205 msg. content,
200- error
206+ display_error ( error)
201207 ) ;
202208 }
203209 crate :: FrameworkError :: UnknownCommand {
@@ -215,7 +221,10 @@ pub async fn on_error<U, E: std::fmt::Display + std::fmt::Debug>(
215221 tracing:: warn!( "received unknown interaction \" {}\" " , interaction. data. name) ;
216222 }
217223 crate :: FrameworkError :: NonCommandMessage { error, .. } => {
218- tracing:: warn!( "error in non-command message handler: {}" , error) ;
224+ tracing:: warn!(
225+ "error in non-command message handler: {}" ,
226+ display_error( error)
227+ ) ;
219228 }
220229 crate :: FrameworkError :: __NonExhaustive( unreachable) => match unreachable { } ,
221230 }
@@ -330,3 +339,26 @@ pub async fn servers<U, E>(ctx: crate::Context<'_, U, E>) -> Result<(), serenity
330339 ctx. send ( reply) . await ?;
331340 Ok ( ( ) )
332341}
342+
343+ /// Helper function to display an `impl Into<Box<dyn std::error::Error>>` and its chain of causes.
344+ fn display_error ( e : impl Into < Box < dyn std:: error:: Error + Send + Sync > > ) -> impl Display {
345+ struct DisplayError ( Box < dyn std:: error:: Error + Send + Sync > ) ;
346+
347+ impl Display for DisplayError {
348+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
349+ let mut e: & ( dyn std:: error:: Error + ' static ) = & * self . 0 ;
350+
351+ Display :: fmt ( e, f) ?;
352+
353+ while let Some ( new_e) = e. source ( ) {
354+ f. write_str ( ": " ) ?;
355+ Display :: fmt ( new_e, f) ?;
356+ e = new_e;
357+ }
358+
359+ Ok ( ( ) )
360+ }
361+ }
362+
363+ DisplayError ( e. into ( ) )
364+ }
0 commit comments