5

When I want to debug my application that throws exception, that means I need to disable the try-catch block like this:

#if !DEBUG
                try
                {
#endif
                    // Do something
#if !DEBUG
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Something wrong");
                }
#endif

Note: I know about break on handled exception of Visual Studio, but the downside is it break at every exception of the same type. EDIT to rephrase my meaning: For example, function A and B both throws NullReferenceException, but I only want to check when A throws it, but not B (handled NulRefExc in B is already correct).

One may ask why I need that. Usually I run ASP.NET MVC code without Debugging (but still in Debug build, which has DEBUG variable), and throwing exception is really great instead of catching it (in dev mode only, of course), because the error page with stack trace will be shown, so we can track the error much quicker.

Is there any cleaner way to write the upper code?

Luke Vo
  • 17,859
  • 21
  • 105
  • 181
  • I dont see how doing this (imagine there's a way) will save you from "the downside is it break at every exception of the same type, no matter where it happens" – user5328504 Apr 26 '17 at 03:17
  • 1
    Do you need catch the global exception? And make breakpoint on it, you will get complete exception with stack trace in debugger. – nyconing Apr 26 '17 at 03:18
  • Google [asp mvc global error handler](https://www.google.ca/search?q=asp+mvc+global+error+handler&oq=asp+mvc+global+e&aqs=chrome.1.69i57j0l5.7663j0j4&sourceid=chrome&ie=UTF-8) – CodingYoshi Apr 26 '17 at 03:21
  • @user5328504 sorry, I rephrased my meaning. – Luke Vo Apr 26 '17 at 03:21

3 Answers3

12

Since C# 6 you also may use exception filters for that:

try
{
    // Do something
}
catch (ArgumentException) when (!Env.Debugging)
{
    // Handle the exception
}

Having Env.Debugging defined somewhere as

public static class Env
{
#if DEBUG
    public static readonly bool Debugging = true;
#else
    public static readonly bool Debugging = false;
#endif
}

As an additional bonus you'll get original call stack in the exception object when it is not caught (due to when test failed, i.e. in debug). With a re-thrown exception you would have to provide the original exception as the inner one and make some extra effort to deal with it.

This approach also allows to enable/disable exception handling based on other condition, a web.config setting for example, which would allow you to swicth without recompilation:

public static class Env
{
    public static readonly bool Debugging =
      Convert.ToBoolean(WebConfigurationManager.AppSettings["Debugging"]);
}
Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
  • 1
    Cool! I never thought about this. Now this question has 2 great answers and I do not know to mark which. P.s: `public const bool` is a shorter version. – Luke Vo Apr 26 '17 at 03:49
  • 3
    For .NET Core you'd use: `catch (Exception ex) when (!_hostingEnvironment.IsDevelopment())` and inject the `IHostingEnvironment` in your constructor. – kipusoep Sep 10 '19 at 07:04
3

just an idea leave the try catch

then do

 catch (ArgumentException)
                {
#if DEBUG
                throw SomeCustomExceptionYouCatchWith_break_on_handled_exception();
#endif
                    Console.WriteLine("Something wrong");
                }
user5328504
  • 734
  • 6
  • 21
  • 2
    you might even have the custom exception get the original exception as a constructor parameter – user5328504 Apr 26 '17 at 03:20
  • Wow, this is nice! Exactly what I need! And in case just a simple code for debugging, a `throw;` statement between `#if` directive is enough :) – Luke Vo Apr 26 '17 at 03:22
  • @DatVM in production do not write to the `Console` but write it to a log. [Where does console writeline go in asp](http://stackoverflow.com/questions/137660/where-does-console-writeline-go-in-asp-net) – CodingYoshi Apr 26 '17 at 03:27
  • @CodingYoshi yes, sorry the code above is just my example, I know about Console.WriteLine does (almost) nothing. My question main aim is in Development environment, where Stack trace is our best concern (but still, we still have try-catch for production) – Luke Vo Apr 26 '17 at 03:38
1

Two things:

  1. How many places are you going to the put the #if DEBUG?
  2. Console.WriteLine is meaningless in ASP.NET. See this for more.

What you should be doing is logging the error to either a database, a file or something. This will avoid all the #if DEBUGs all over the code. Please see this for more on logging.

This has additional benefits:

  1. You will be able to see what your errors look like so when you go into production you will get the same information. If you do not have enough information, in the log, during development, it gives you a chance to change the error message and ensure the stack trace is there. This will be helpful when you go into production because now you have better errors.
  2. Your code is cleaner
Community
  • 1
  • 1
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64