Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
How are you formatting your try..catch.finally blocks? Especially when only wrapping it around a small amount of code, it blows everything and makes code pretty unreadable and unsightly in my opinion.
Such as:
try
{
MyService service = new Service();
service.DoSomething();
return something;
}
catch (Exception ex)
{
LogSomething();
return somethingElse;
}
finally
{
MarkAsComplete();
service.Dispose();
}
These 7 lines of code turned into a 16-line mess.
Any suggestions on better try..catch..finally formatting?
Actually, this reads very well to me. If your actual code looks a lot like this, then I really wouldn't worry about it. It is VERY clear what is happening.
If your actual code is more complex, then consider breaking the blocks into well-named methods.
you can use a using block instead of an explicit Dispose(), or else you probability have to check for null before disposing it, using blocks does that for you. unfortunately it does increase nesting =/
try
{
using(MyService service = new MyService())
{
service.DoSomething();
return something;
}
}
catch (SpecificException ex)
{
LogSomething(ex);
return somethingElse;
}
finally
{
MarkAsComplete();
}
Well, I think that's just fine. Some of this gets intot he curly brace placement debate. You could do this:
try {
//
} catch(Exception ex) {
//
} finally {
//
}
I prefer what you have though. However, you might want to consider revising your code to only have one return statement. I find that is a little better design.
I format the code with the brackets on the same line:
try {
MyService service = new Service();
service.DoSomething();
return something;
} catch (Exception ex) {
LogSomething();
return somethingElse;
} finally {
MarkAsComplete();
service.Dispose();
}
I prefer to add blank lines if I want more spacing. That also works as a separator between logical blocks of code.
You might think about containers (very smart factories) and advice (to handle all the messy details).
Dear Mr. Container Sir,
Whenever I request from you an instance object of the interface ISomething,
please construct for me an instance of the concrete class SomethingImpl;
in addition, please see to it (however you do it) that, whenever I call a
method on this instance, it is wrapped within a complicated and messy try-
catch-finally which logs exceptions and mark calls as completed. That way,
all I have to do is write the business logic that goes into the SomethingImpl
and I don't have to worry about all the messy infrastuctural details.
Sincerely,
Mr. Agile.
You might see this, in code, as:
//a class that knows how to take care of the messy infrastructure details
public class MyMessyInterceptor : IInterceptor {
public void Intercept(IInvocation invocation) {
//handle the messy details of continuing with the method-invocation,
//but within a try-catch-finally that includes exception handling and
//call logging.
}
}
//a function that will configure a container (very smart factory)
public IContainer CreateContainer() {
var builder = new ContainerBuilder();
//tell the container-builder about the interceptor
builder
.Register(c => new MyMessyInterceptor())
.Named("keep-my-code-clean")
;
//tell the container what to do when you ask it for a ISomething
builder
.Register<SomethingImpl>()
.As<ISomething>()
.InterceptedBy("keep-my-code-clean")
;
return builder.BuildContainer();
}
//some function out there in your code somewhere that needs to make a
//service call; there's hundreds of functions out there just like this
//in your code, and they all just got much simpler
public object GottaGoDoSomething() {
//find the container
var container = GetTheSingletonContainerObject();
//ask for an instance of ISomething - it knows to provide a
//SomethingImpl wrapped in an interceptor that takes care of all
//the logging and exception handling
var something = container.resolve<ISomething>();
//call the big method
return something.DoSomething();
//magically (not really), the exception handling and logging are
//already taken care of
}
Coming up with the interceptor class happens just once. Registering each interceptor and service class also happens just once. Setting up the container (very smart factory) is certainly complicated.
However, every place in your code that has to use the service object, and has to embed that use within complicated and messy infrastructure details such as exception handling and logging, just got very clean and very uncomplicated. There's only one CreateContainer, but there are hundreds of GottaGoDoSomethings, so that's a whole lot of easy at the cost of a little bit of complicated.
(Notes: The code example uses the Autofac container framework and the Castle interceptor framework. I am aware that this is an example of the service-location pattern, not the dependency-injection pattern, but the point was to illustrate interceptors and registering them with a container, not to illustrate dependency-injection.)
Whitespace. As a bare minimum I always put one line of whitespace before every return statement and in between "doing stuff" and "creating variables" sections of code.
try
{
MyService service = new Service();
service.DoSomething();
return something;
}
catch (Exception ex)
{
LogSomething();
return somethingElse;
}
finally
{
MarkAsComplete();
service.Dispose();
}
much better.
I think your formatting reads well too. My suggestion would be to only use the catch statement sparingly. Only use it when you actually need to catch something. Otherwise you can let other parts of the program handle the exception. The whole "fail early" concept.
try
{
//do something that may throw an exception.
}
finally
{
//handle clean up.
}
//let a method further down the stack handle the exception.
Personally, I tend to follow the preceding style in my code... It gives room to make comments, and shows the flow of my logic better.
I have a widescreen that I turn on it's side, so the whitespace allows the various columns to line up well and doesn't hurt me that much that because I have so much screen real-estate as it is...
try { // getting a service
MyService service = new Service();
service.DoSomething();
return something;
}
catch (Exception ex) { // the fact that a service might be full/timedout
LogSomething();
return somethingElse;
}
finally { // remove any resources the service may still hold.
MarkAsComplete();
service.Dispose();
}
I too, like what you originally had. Physical lines in a .cs file don't cost you anything, and don't change your final output code. So use all you need in order to provide the best readability for you or your team.
In fact, you should actually try to use more lines than the 16 you show here when you code, by adding comments for yourself or others.
By adding
// a comment that says what's going on
frequently, you can better remind yourself what this Try.Catch is supposed to be doing when you go back to it after 6 months.
I always try and refactor out all of my try catch blocks and encapsulate them in their own method.
This always seems to make everything more readable, plus it's a good programming practice to make your methods only do one thing. Odds are that if you have code above and below your try-catch-finally statement, then you're doing more than one thing.
If you really want to get rid of the mandatory but ugly formatting (yes I agree :p)
go for Aspect Oriented Programing, and you will get the try...catch...finally
embedded for free in your assembly and exception logged automatically.
Try PostSharp or Spring.Net
Related
Is aspect oriented programming really a solution for logging? Consider the following service call:
public MyServiceProxy : IMyServiceProxy {
public IEnumerable<string> GetAllData() {
try {
proxy.GetAllData();
} catch (NotSoCriticalException notCriticalEx) {
} catch (CriticalException criticalEx) {
}
}
In this example, I have 3 kinds of ways on how I log my message. The first one is when everything went fine, with log4net something like "logger.Info()", but even if both of the others fail, one might be critical, the other could suggest the user might try it again later, hence not considered critial. In all 3 cases, I have to log, but the advices on how to handle the aspect are totally different. How does AOP could help in such a scenario?
The AOP framework of your choice should let you create pre/post handlers for method calls. Therefore, this is the internal proxy.GetAllData() that should be wrapped.
In such wrapping handler, you catch exceptions and rethrow them so that the original code works normally, however the logging code gets the full access to the exception info.
In the other hand, wrapping the GetAllData at the class level doesn't make much sense as there is no detailed information passed to the outside of the method.
I spent some time looking for a way of resolving my issue but with no success!
Here is my problem: I have got some code that does the following:
public void DoSomething(){
try{
DoStuffThatCanThrowException();
}catch(Exception e){
// Do nothing...
}
}
As you can see, the try catch block swallows all exceptions that can be thrown in the DoStuffThatCanThrowException().
I am trying hard to think of a way to write a unit test that basically ensures that no exception is thrown in the DoStuffThatCanThrowException(). The difficulty here is that I can neither change the try catch block nor the DoStuffThatCanThrowException() method.
Any hints are highly appreciated.
EDIT
One important detail I forgot to mention, I can not call DoStuffThatCanThrowException directly as it is internal and so is not visible from the outside world.
Can't you just call DoStuffThatCanThrowException from a unit test itself, therefore not being surrounded by try...catch at all?
Edit: Just seen that your method is internal. I'd suggest for the purposes of your test you make a public method which wraps it. That way you can test things temporarily. Once you are sure that the method cannot fail you have no further need for the try...catch in the first place.
Sorry for mess with the answer, maybe reflection will help you to dig in?
ClassContainingInternalMethod cl = new ClassContainingInternalMethod ();
//any private or internal method you want here.
MethodInfo dynMethod =
cl.GetType().GetMethod("DoSomeStuff", BindingFlags.NonPublic | BindingFlags.Instance);
dynMethod.Invoke(cl, new object[] {});
Can you call DoStuffThatCanThrowException() directly? If not, make a subclass of the original class that contains that try catch block and call it from there without the catch block.
class ClassUnderTest extends OriginalClass
{
#Override
public void functionToTest()
{
DoStuffThatCanThrowException()
}
}
Also, testing for the absence of exceptions is difficult. You need to find all the potential exceptions that can be thrown and test around that. Even then, all you're saying is that "give these tests, no exceptions were thrown". This is less powerful than saying "Exceptions will never be thrown", but is usually good enough.
Add a positive assert immediately after the call to DoStuffThatCanThrowException(), within the try block. If an exception occurs then the assert won't be executed. Or, add a negative assert inside the catch block. Not sure if this answers your question; it's not very clear.
So I am recently writing a relatively complex application written in C# that performs an array of small tasks repeatedly. When I first started the application I realized that a lot of the code I was typing was repetitive and so I began encapsulating the majority of the app's logic into separate helper classes that I could call as needed.
Needless to say the size of my app (and amount of code) was cut in half. But as I was going through I noticed something else in my application that seemed to be repetitive and looked like it could be improved.
Now most of my methods in my helper classes are either making a HttpWebRequest or performing save/delete operations on files. Having said that I need to handle the possibility that eventually the call won't complete, or the file can't save because there isn't enough space, or whatever. The problem I'm running into is that I have to keep writing try/catch statements every time I call one of the methods. On top of that I have to retype the error message (or Eventually a status message. I would like to know when it succeeds as well).
So here's kind of a snippet of what I have to type:
try
{
ItemManager.SaveTextPost(myPostItem);
}
// Majority of the time there is more than one catch!
catch
{
//^^^Not to mention that I have to handle multiple types of exceptions
//in order to log them correctly(more catches..ugh!)
MessageBox.Show("There was an error saving the post.");
//Perform logging here as well
}
From what I have concluded so far is:
To me this is overkill having to write this over 50 times for my app.
Sounds like I should be including this in the helper class and
include the full set of catches.
But how could I know the result? I was maybe thinking of returning a
string that contains the error/success message.
Really for these types of methods it doesn't require the method from which the helper method is being called from to enclose it in a try/catch block.
Is this approach correct? Is there another way of doing this? Should I be using a try/catch in the calling method at all? Since this kind of my first shot at this I would really like to hear what others who have handled this scenario have to say.
I think putting the try/catch in the method you are calling is perfectly fine. You can return error/success codes to the calling code in a variety of ways. .NET and c# handle enumerations nicely, so you could have ItemManager.SaveTextPost(myPostItem, out errorCode); where errorCode would be an enumerated value that would let you know if any problems occurred. It could also be as simple as having the method return a bool true if successful, false if otherwise. There are many ways that you could handle that issue, but as far as I'm concerned putting the try/catch in the method is the preferable way of doing things.
AOP libraries like PostSharp are designed to handle cross-cutting concerns exactly like this.
If all these helper methods employ the same boilerplate try catch -> handle multiple types of exceptions, then you can write one aspect that does that, and decorate all of the relevant methods with the appropriate attribute.
There is no single perfect rule for exception handling, so the answer is: It depends. In general you should only catch exceptions, if you know how to handle them. In your example my first question would be, if the application can continue to run after this error and would still be in a valid state. If not, you should rethrow the exception after logging. Then think about nesting exception: You can catch an exception, add information by nesting it into another and throwing that exception. If you design your exception classes and handlers carefully, your logging and displaying code should become much simpler than you expect it. But the details obviously depend on your application.
All of these ways are great options. One thing you want not to do is to use a try {} catch {} for flow control. This means something like this (again avoid this)
Void SomeMethod()
{
try
{
while(somecondition)
{
try
{
}
catch (Exception ex)
{
}
}
}
catch (Exception ex)
{
.....
}
Instead you want to code defensively.
You should throw exceptions in your helper methods by checking with if blocks if every argument is correct, every file is reachable... then if needed, implement some try catch blocks in your helper methods and throw exceptions when catching.
Finally, enclose these helper methods by a try catch block, but at this time, really catch the exceptions:
try
{
ItemManager.SaveTextPost(myPostItem);
// SaveTextPost can throw some exceptions (that you know)
}
catch (Exception e)
{
// You know the exceptions that SaveTextPost can return, so threat them
// correctly
if (e is FileNotFoundException)
MessageBox.Show("The file was not found when saving the post.");
else if (e is ArgumentNullException)
MessageBox.Show("The post can't be null to be saved.");
else
MessageBox.Show("There was an error saving the post.");
}
At the end, you need to treat the error and show an error message to the user. You only can decide if the MessageBox.Show should be implemented in the helper method or in the class calling the helper method.
Personally, I think helper methods are destined to be used by any developer that will run your code, so you should let him decide what he wants to do with the error. That means throwing exceptions in the helper method.
Try/Catch is a good solution. One suggestion, I like to use this to stem the flow of errors: exception catching:
try
{
}
catch (Exception ex)
{
ShowExceptionError(ex);
}
Then I will simply throw all exceptions to a single method, and let the method handle each.
Kind of like this:
private void ShowExceptionError(ex)
{
string errorMessage = "Type of error:" + ex.GetType().ToString();
string stackTrace = ex.StackTrace();
MessageBox.Show(errorMessage + "\n\n" + stackTrace);
}
My personal take on exception handling is.. add try {} catch {} where it makes sense.
For example always use a try catch when calling "untrusted" code, i.e. modules or plugins. otherwise if you are going to catch an exception make sure you can do something meaningful with it. If not, allow the exception to bubble up to a point where you can.
There are few things worse than trying to debug an app where the developer caught an exception and returns a bool. Just sayin'
Hey everyone, I was thinking about passing method blocks around as arguments to helper classes that built in exception handling but it's one of those things that is intuitive and I'd like to submit it for criticism, insight, or advice.
I would like to note up front that this is NOT how I do all of my exception handling, but there are cases where I find this structure more "readable."
For example, I have a scenario where I'm showing a preview image but if that fails (this is a real scenario where I'm previewing images and certain GIF/BMP formats cannot be previewed) it's simply a scenario where I display an alternate image instead of preview. The try/catch code block that looks like this:
try
{
alternatePreviewImage.SetSource(fs);
}
catch (Exception ex) {
requiresSpecialPreview = false;
previewImage = new BitmapImage(new Uri("Images/NoPreviewAvailable.png", UriKind.Relative));
}
So I'll leverage a helper class that takes a method parameter to make it look like this:
if(!ErrorHelper.RunWithSuccessNotify(()=> alternatePreviewImage.SetSource(fs))){
requiresSpecialPreview = false;
previewImage = new BitmapImage(new Uri("Images/NoPreviewAvailable.png", UriKind.Relative));
}
The ErrorHelper.RunWithSuccessNotify is quite simple:
public static bool RunWithSuccessNotify(Action code) {
bool success = true;
try
{
code();
}
catch (Exception ex)
{
success = false;
}
return success;
}
Let me again underscore that it is useful for these low impact scenarios, as well as others where I may be able to suppress the exception:
public static void RunWithErrorSuppression(Action code) {
try
{
code();
}
catch (Exception ex)
{
// pass
}
}
The approach could be more detailed too, to allow for capturing the exception:
public static void ExecuteWithLogging(Action code, Action<Exception> handles) {
try
{
code();
}
catch (Exception ex)
{
handles(ex);
}
}
So what are thoughts on this set of tactics to centralize exception handling? If it is a bad direction, are there specific reasons why it might end up getting me in trouble?
The main problem I would have with this approach is catching Exception is generally considered bad form. If there was some way to specify which type of exception to catch I might buy it, but I believe that has to be specified at compile time. I also wouldn't feel completely comfortable with catching all exceptions and rethrowing the ones that don't match.
Remember, when you catch an exception, you're essentially saying that you can handle the error in some meaningful way. Obviously, the code above can't handle StackOverflowException or MissingMethodException.
Don't trap all the exception, parametrize the one you want:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProvaException
{
class Program
{
static void Main(string[] args)
{
int a = doWithException<int>(divide, 0, typeof(DivideByZeroException), x => 300);
Console.WriteLine(a);
Console.ReadKey();
}
public static int divide(int b)
{
return 10 / b;
}
public static T doWithException<T>(Func<T, T> a, T param1, Type exType, Func<Exception, T> handFunction) {
try
{
return a(param1);
}
catch(Exception ex) {
if(exType.Equals(ex.GetType())) {
return handFunction(ex);
}
else
throw ex;
}
}
}
}
Not very C# like, but it can be useful in same case (when you want to abstract handling exception).
You have to write a different type signature for every type of function, because C# doesn't support currying. Veeeeeeeeery boring. :D
It's not a very elegant solution, but it gives you an hint on how things works in functional languages. It's very fun to learn.
Hello i don't know if it scale well but for now my team is using it in our measurement software to handle special exception (like communication with some measurement device lost) and restart the measurement in this case.
For now it's working well especially in cases where the important / non repetitive part of the code is in the function (Action parameter) being called and not really in the exception handling.
The best case being that they even could be nested and the main code kept readable.
On the other side you are hiding what exactly your exception handling is doing behind a function name, so it should be simple or clear enough to be understandable just by the name of the function, otherwise you are obfuscating something from the future readers of your code (yourself included)
My initial thought is simply that passing complex anonymous delegates around smells bad. There's nothing stopping someone from dumping an anonymous delegate with complex logic into the ErrorHelper methods. Such logic then becomes difficult to test. I would prefer logic to be passed only in an object, which to me seems to be a better understood technique. To me anonymous delegates (and lambdas) are for very simple logic extensibility, like comparison logic. The mechanics of anonymous delegates are powerful and can be used for other things, but with great power comes great responsibility. =)
What you achieve with your technique is the ability to cleanly change the exception handling strategy at runtime. But is this an actual requirement?
Have a look at THIS and maybe whip out the ol' Reflector on it for a bit. Seems to me like the same things are done there but possibly in a more complete way... It seems very powerful...
If I've understood what you're trying to do, then it feels horrible to me as a standard error management pattern. That's a warning sign right there, as it took me a while to grasp your idea.
Unless there's a good reason, code should be explicitly available in the method for any maintenance developer to view and modify, not passed around from other locations. Just because a feature exists doesn't mean that it's useful in most situations. In this case, I can't see any benefit from the obfuscation.
BTW, I think you're nailing the corpse to the wall by catching System.Exception. The normal rule is not to catch an exception unless you know what the exception is and/or you need to know the exception detail for some reason.
A commonly-used pattern for recovery in the event of an unknown exception looks something like this:
bool exceptionHappened = true;
try
{
alternatePreviewImage.SetSource(fs);
exceptionHappened = false;
}
finally
{
if ( exceptionHappened )
{
requiresSpecialPreview = false;
etc;
}
}
I'm looking for an "elegant" way to suppress exceptions when calling a method.
I think the following code is way too verbose:
try
{ CallToMethodThatMayFail(3); }
catch {}
Is there some syntactic sugar I can use to say "I don't really care if this method fails"? I want to call the method and continue execution regardless of what happens with the method.
It is rarely a good idea to ignore/swallow errors...
To allow re-use, the only option you have is something like a method that takes an Action:
static void IgnoreErrors(Action action) {try {action();} catch {}}
But you haven't exactly saved much by the time you've done:
SomeHelper.IgnoreErrors(() => CallToMethodThatMayFail(3));
I'd just leave the try/catch in place...
Re the question in the comment:
static void IgnoreErrors<T>(Action action) where T : Exception
{
try { action(); } catch (T) {}
}
SomeHelper.IgnoreErrors<ParseException>(() => CallToMethodThatMayFail(3));
but I would still find it clearer to have the try/catch locally...
Nope this is it.
And it's a good thing it's verbose. If you're suppressing a possible exception you better have a very good reason. The verbosity will help you or the next person who looks at the code in a few months.
Using Castle, you could do something like this:
public class ExceptionSuppressionInterceptor : Castle.Core.Interceptor.IInterceptor
{
public void Intercept(IInvocation invocation)
{
try {
invocation.Proceed();
}
catch (Exception ex) {
// Suppressed!
}
}
}
And decorate the class you want to suppress exceptions for like this:
[Interceptor(typeof(ExceptionSuppressionInterceptor))]
public class GoodPracticeBreaker {
}
But you really probably shouldn't.
I don't know of anything more terse. I suppose you could do some AOP or similar for something more fancy.
The .Net convention is that classes implement a TryCallMayFail() method and a CallMayFail() method and the caller chooses which one to uses but the TryCallMayFail() method would include exactly what you have there.
No, there's no better way to do this, and there's a good reason for it. The exception you see may mean more than "the method failed". It may mean, "the system is failing".
You probably should at least log the fact of the failure, in case it turned out to be important after all.
Why do you say this is too verbose? If you are trying to save keystrokes, you can just use a code snippet. If you are concerned about readability, then I think that an AOP method would be less clear to another maintainer (at least initially) and for me, this outweighs the verbosity.