Sometimes feel like a try catch block is just an extra scope around an already existing scope.
Original:
public void Method()
{
try
{
// do something
...
}
catch (CustomException e)
{
DoSomethingWithCustomException(e);
}
catch (Exception e)
{
DoSomethingWithException(e);
}
}
Simplified:
public void Method()
{
// do something
...
catch (CustomException e) => DoSomethingWithCustomException(e);
catch (Exception e) => DoSomethingWithException(e);
}
In my opinion the "try" part of the block is meaningless if you use it for the entire scope. And you can use the original syntax beside this. This syntax can be useful in foreach or any other loop.
So is it possible enable a syntax like this?
So is it possible enable a syntax like this?
Not in the current version of C#. You can always suggest a language feature here, but first search the existing proposals to see if it's been proposed already.
A quick search for "catch" in the issues led to this almost identical proposal:
https://github.com/dotnet/csharplang/issues/908
Note that it has 1 upvote and 15 downvotes. There's only one comment on it, but it gives at least some feedback as to the viability of the feature.
You might also look at third-party libraries like PostSharp that can inject exception handling at a method level.
Related
In the following code, NDepend reports a violation because of a nesting depth of 6 (1 for each catch) and the limit is 5. So it gets flagged in this rule:
Quick summary of methods to refactor
Is having just a single catch for the more general IOException and having code within that catch to distinguish between DirectoryNotFound, PathTooLong, and other IOException the best way to go? I don't want to increase the nesting depth limit since it's a valid limit for most cases. What about the case where none of the exceptions are in the same hierarchy and combining isn't an option? Is creating an attribute and altering the rule to disable the violation for just this method the only way to go?
private static void _TryDeleteFile(string filename)
{
try
{
File.Delete(filename);
}
catch (ArgumentException innerEx)
{
// do something
}
catch (DirectoryNotFoundException innerEx)
{
// do something
}
catch (PathTooLongException innerEx)
{
// do something
}
catch (IOException innerEx)
{
// do something
}
catch (NotSupportedException innerEx)
{
// do something
}
catch (UnauthorizedAccessException innerEx)
{
// do something
}
}
Firstly try/catch blocks are not as elegant to work with in c# as they could be, and that's just something we have to live with for now.
Secondly, there are many ways to reduce nesting but they will always come at the expense of some other form of complexity, so you need to be careful. Remember that NDepend is recommending that you reduce nesting because it is guessing that your code might be hard to read or maintain. It could be wrong, or it could be that there are no better options given the tools you have available.
In my mind, the way forward really depends on the work you are doing inside each of those catch blocks. If it is very simple, such as just returning a string error message and nothing else, then I think your code will be fine as is. However if you are doing different types of logic in each block, and particularly if you have repeated logic for different exception types, then your code may become messy.
The refactoring might be to keep a collection of 'exception handlers' (either classes or Actions) in a dictionary, factory class or IOC kernel. You can then source the exception handler in one line of code. This will reduce nesting, but introduce its own complexity. Something like this:
try
{
/* Your code */
}
catch(Exception ex)
{
var exceptionHandler = _exceptionHandlers[ex.GetType()];
exceptionHandler.Execute(ex);
}
There are many different ways of achieving essentially the same thing: you push each blob of logic out into it's own class/method/lambda and then you have an intermediate class/method/Dictionary that you use for sourcing the correct logic.
Here are two previous questions regarding this topic:
Catch multiple Exceptions at once?
More Elegant Exception Handling Than Multiple Catch Blocks?
I was working today and thought this might be an appropriate syntax should this feature ever be added to the C# language. Anyone have any opinions about it?
The type of e must be a base type or interface of every exception type listed.
Edit: In this example, the catch block handles either ArgumentNullException or ArgumentOutOfRangeException and places the exception instance in a variable of type ArgumentException called e. It doesn't handle any other type of ArgumentException other than the two listed. I think there was some confusion about the associativity of the , and the as.
Edit 2: If the listed exceptions all upcast to a variable of the type of e, then the code compiles cleanly to MSIL without any casts or explicit type checks, making it faster (potentially significantly) than the current syntax of catching ArgumentException followed by a throw; if it's not one of the two you intended. The problem is even more obvious if you're catching Exception and checking for two possible types to handle and rethrowing if it's something else.
try
{
}
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e)
{
}
See this:
Cool or Stupid? Catch(Exception[NamingException, CreateException] e)
My answer to that question is that they should let you "stack" them like with using blocks:
try
{
}
catch (ArgumentNullException e)
catch (ArgumentOutOfRangeException e)
catch (ArgumentException e)
{
}
Though I see you're going for and rather than or . Personally I don't see the and approach as very useful, because you're already constrained to a real non-interface exception type and there's no dual-inheritance.
Inclusion of this feature is planned for Java 7 with the following syntax:
try {
return klass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}
Edit: I think the intention is for the static type of e to be the most specific common superclass of the listed exceptions. (In Java, only instances of class java.lang.Throwable can be thrown, hence catching with a common super interface is of limited utility since the exception can not be re-thrown.)
You can already do this, just
try{}
catch(Exception e)
{}
since all exceptions derive from System.Exception. And you would do just as you would above, determine the type of the exception in the catch block itself.
If ArgumentNullException and ArgumentOutOfRangeException have different interfaces, will be a pain to cast correctly;
For instance ArgumentOutOfRangeException have an ActualValue property; if you had to use it, you'll end with something like:
if(e is ArgumentOutOfRangeException)
{
// use e.ActualValue
}
else
{
// use e.Data
}
I don't find myself wanting this very often in C#, whereas in Java I find there are various situations where I have to catch a bunch of checked exceptions and wrap them all in a different exception that my method is declared to throw.
That's something I'd possibly like some syntax for:
try
{
}
wrap (OneException as AnotherException)
catch (HandleableException e)
{
// Actual handling for some exception types
}
... but again, I find myself doing that much more in Java than in C#.
There are other enhancements which are way higher up my list for C# than this :)
That would only work if you do not declare an instance (e). If you reference the e inside the block, what is it?
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;
}
}
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
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.