Dennis Gorelik (
dennisgorelik) wrote2019-05-03 02:36 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Entry tags:
Try-catch for delegate is unmaintainable
Couple or years ago we tried to reuse exception handling code and created this method:
The idea was that if we know that a method may crash then we would just pass that method as a "tryAction" parameter.
Then ExecuteEmailCrashSuppressWebException() will swallow web exceptions, and will notify us (developers) about all other exceptions.
We wanted to avoid repeating try-catch boilerplate code by reusing ExecuteEmailCrashSuppressWebException().
That attempt [to reuse try-catch] failed miserably. Every tryAction method needed its own custom exception handling:
- In some cases we needed to swallow WebException, but in other cases we wanted to log it.
- In some cases we wanted to write to one "{tryAction}.log" file, but in other cases we wanted to write to differently named log file, or not to write to log file at all.
- Log message content was quite different for different tryAction methods.
Eventually we deleted ExecuteEmailCrashSuppressWebException() and wrapped every individual method that needed custom exception handling - by its own try-catch block of code.
My conclusion is:
Try-catch block should wrap only direct method calls.
Almost never try-catch should wrap Action/delegate invocation (such as "tryAction()").
The reason why wrapping delegate invocation with try-catch does not work is that "catch" implementation is very custom for every individual method.
Merging all these custom implementation into a single "catch" block produces unmaintainable mess.
public static void ExecuteEmailCrashSuppressWebException(Action tryAction, ActionreportAction) { var tl = new TimeLog(); try { tryAction(); } catch (WebException) { return; } catch (Exception ex) { string displayName = tryAction.GetDisplayName(); string message = CookMessage(displayName, reportAction, tl, ex); string subject = $"Win crash: {displayName}()"; Log.ToFile(message, displayName + ".log"); EmailToDevelopers.EmailTextIfSubjectWasNotSentRecently(subject, message); } }
The idea was that if we know that a method may crash then we would just pass that method as a "tryAction" parameter.
Then ExecuteEmailCrashSuppressWebException() will swallow web exceptions, and will notify us (developers) about all other exceptions.
We wanted to avoid repeating try-catch boilerplate code by reusing ExecuteEmailCrashSuppressWebException().
That attempt [to reuse try-catch] failed miserably. Every tryAction method needed its own custom exception handling:
- In some cases we needed to swallow WebException, but in other cases we wanted to log it.
- In some cases we wanted to write to one "{tryAction}.log" file, but in other cases we wanted to write to differently named log file, or not to write to log file at all.
- Log message content was quite different for different tryAction methods.
Eventually we deleted ExecuteEmailCrashSuppressWebException() and wrapped every individual method that needed custom exception handling - by its own try-catch block of code.
My conclusion is:
Try-catch block should wrap only direct method calls.
Almost never try-catch should wrap Action/delegate invocation (such as "tryAction()").
The reason why wrapping delegate invocation with try-catch does not work is that "catch" implementation is very custom for every individual method.
Merging all these custom implementation into a single "catch" block produces unmaintainable mess.
no subject
And sure, never ignore exceptions.
no subject
What does "monadic nature of computing" mean?
> never ignore exceptions
As of now, API of one of our partner is down for ~40 hours ("(500) Internal Server Error.")
If I suppress these error messages - would you call it "ignore exception"?
no subject
no subject
What conclusions do you make from "500 Server Error"?
What conclusion do you make from "500 Server Error" that is not fixed for 2 days?
no subject
no subject
So increasing delay probably does not worth the effort.
I already notified the API owner (after ~36 hours).
Another 12 hours later they are still not able to fix the problem.
They asked me for a screenshot.
Several years ago it was a capable team (they usually fixed problems within couple of hours), but it looks like now this company partially abandoned that part of their business.
no subject
no subject
no subject