0

See this code:

 try
    {
        int val = GenericLibrary.ConvertToInt(userInput);
        return "Valid number";
    }
    catch (Exception)
    {
        return "Invalid number";
    }

I writing a console application that has many try , catch block.I want to handle exception in cleaner way and follow DRY principle.

What is the best way for handle error in Console application c#?

Can I use Func or Action?

Can i use aspect oriented programming and how?

nathanchere
  • 8,008
  • 15
  • 65
  • 86
Yazdan Bayati
  • 184
  • 1
  • 2
  • 6
  • Not sure if it's what you mean, but check this out: http://stackoverflow.com/questions/3133199/net-global-exception-handler-in-console-application – Dimitar Dimitrov Jul 21 '13 at 04:52
  • @DimitarDimitrov think he want to delete all try catch and handle centralize –  Jul 21 '13 at 04:58
  • @ShahroozJefriㇱ Well, that's exactly what the link is referring to :) – Dimitar Dimitrov Jul 21 '13 at 04:59
  • Your question covers validation and error handling in a very broad context. Even if you get an answer you like, you really need to understand the problem you're trying to solve better. – nathanchere Jul 21 '13 at 05:09
  • 2
    @FerretallicA is spot on, **exception handlers should be used exceptionally** – Jeremy Thompson Jul 21 '13 at 05:11
  • 1
    I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Jul 21 '13 at 05:13

3 Answers3

4

I want to clarify, cleaner - if you only want to write the error handling code in one spot then you could use AOP (eg PostSharp). But realise with error handlers via AOP they would then be compiled everywhere in your exe.

Also keep in mind this defeats the rule that exception handlers should be used exceptionally.

I'm not sure why you wrap a string cast to an int in a Try-Catch.

You could just handle unexpected exceptions in one place by setting up Global Exception handlers Application.ThreadException and AppDomain.CurrentDomain.UnhandledException. Remember to handle all the exceptions you expect such as the string to int cast.

You could use a Func for this cast but it would be easier with the simple method: Integer.TryParse.

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
3

What is clean does depend on a lot of factors. A general exception handler via PostSharp or other AOP handlers e.g. the Exception Handling Application Block from the Enterprise Library does even let you configure your policy. Although a nice idea it has never gained much traction until the policy injecion application block was in place which is also an AOP framework which would allow you to handle exceptions centrally in a configurable way.

However in reality exception handling remains hard. The first rule should be to never hide exceptions. You can catch them of course but you should always log them when you do not let them propagate further. What if your GenericLibrary uses some config file to decide in which locale the integers should be processed and it does not find its config file? You get repeated errors but you will never find out the root cause until you debug it because you throw away the exception object and return a string instead.

An equally bad "handling" strategy is to to

catch(Exception ex)
{
   Log("Error has occured: {0}", ex.Message);
}

This will give you the error messsage but you loose the complete call stack and any inner exceptions. This is especially bad if you receive some generic wrapper exception like TargetInvocationException which contains only a generic error message.

The right handling strategy depends quite much on your specific context. If you mean with console application a small application which is not delivered to customers then it is usually the simpliest to remove all catch handlers in a first pass and handle them globally in the main method. Then when you have got experience with the most common non fatal errors you can re add the necessary catch handlers to regain robustness. Now you continue to work on non fatal errors but you keep the failfast strategy for the fatal ones.

Any previous answer here does only give you the advice to use this or that strategy but you need to decide which exceptions are non critical to your app on a case by case basis. When you catch everything you won´t find out why your app did nothing because of internally catched errors. If you have no handling at all your app will terminate on every non fatal error (e.g. it can be ok to return 0 if the value cannot be parsed in your app).

For a small console app I would

  • Remove all catch blocks
  • Even in the Main method

This way you get automatic logging of the .NET Framework in the application event log with no extra effort if your app does crash. If your console app is executed e.g. as a scheduled job printing the output to the console will not help you much. This is the cleanest way of handling exceptions: No handling at all and let your application crash so you can find out what went wrong in the application event log.

If you deploy besides your executable the pdbs for release builds you also get the line numbers and file infos which makes it really easy to spot the error in most cases.

If your application is mission critical or delivered to customers it can happen that you need to employ some logging framework to log to some private log file. The difference between a console application and a windows application is only a flag in the PE header. A Windows application will detach from the currently started console whereas a console application will remain attached to it. That is the only difference. You can also create a WPF application in a console application but it will block your console as long as it will run which is perhaps not the thing you did want.

But if you switch to a Windows application you can allocate a new console to make Console.WriteLine happen to work again and you can continue to use printf debugging which is perhaps the most used debugging method although a quite old fashioned one.

Usually you would add a tracing library to your application to follow your application flow which is by default off. Logging should also be done which is always on which does only error logging. With that approach you have more troublesshooting options at customer machines if error logging is not enough.

Alois Kraus
  • 13,229
  • 1
  • 38
  • 64
  • +1 for sportsmanship. I think this answer is suited to the OP's level. You wrote `When you catch everything you won´t find out why your app did nothing because of internally catched errors` this isn't necessarily true, see how you can get the stacktrace and etc from the Global Exception Handler, see [last paragraph](http://stackoverflow.com/a/4053325/495455), if its an internal .net error you need winDBG when you're digging that deep. – Jeremy Thompson Jul 21 '13 at 07:13
  • The global exception handler (I mean AppDomain.CurrentDomain.UnhandledException) is only called when the thread start method is left with an exception. If you place a catch around the main and every thread method you do execute it will never be called. Yes I was unclear in my wording. I did mean that you will not find out without debugging why your app is misbehaving when you silently catch everything. – Alois Kraus Jul 21 '13 at 07:27
  • No worries, thanks for clarifying, that's the only reason I picked you up on it:) – Jeremy Thompson Jul 21 '13 at 07:28
  • Thanks for the upvote. More elaborate answer take longer and are often not voted at all. – Alois Kraus Jul 21 '13 at 07:34
0

If you can want use Func see this: You can use this

public static class SafeExecutor
{
    public static T Execute<T>(Func<T> operation)
    {
        try
        {
            return operation();
        }
        catch (Exception ex)
        {
            // Log Exception
        }
        return default(T);
    }
}

var data = SafeExecutor.Execute<string>(() =>
{
    // do something
    return "result";
});