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?
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"]);
}
just an idea
leave the try catch
then do
catch (ArgumentException)
{
#if DEBUG
throw SomeCustomExceptionYouCatchWith_break_on_handled_exception();
#endif
Console.WriteLine("Something wrong");
}
Two things:
How many places are you going to the put the #if DEBUG?
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:
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.
Your code is cleaner
Related
Setup:
1) MSVS 2015, Option -> Debugger -> "Just My Code" is checked.
2) This sample code placed within some class and called during startup:
static bool TestIgnoreException()
{
Exception ex;
return TrySomething(out ex);
}
[DebuggerNonUserCode] // Prevent exceptions from stopping the debugger within this method.
static bool TrySomething(out Exception exOut)
{
try
{
if (Environment. MachineName.Length != -1)
throw new Exception("ThrewIt.");
exOut = null;
return true;
}
catch (Exception ex)
{
exOut = ex;
return false;
}
}
3) Launch Debugger
Expected result is that TestIgnoreException() runs silently and returns false.
Actual result is the debugger stops in TestIgnoreException() even though there should be no exception being processed at that scope.
4) Also re-tried using [DebuggerHidden] instead, same results.
Motivation:
The motivation is for cases where some API that is out of your control does not provide a "Try" method and instead only indicates failure by using exceptions.
One of numerous such examples is .NET TcpClient.Connect(host, port). Say a program always tests some connections during startup, the debugger should not stop on this particular section of code each time.
Using the standard "break when thrown" exceptions checkboxes is is not good because it works globally by type. It cannot be configured to work locally. Also other developers who check out the code should automatically skip the exception as well.
Mystery solved. It is indeed a known issue that is new to MSVS 2015 because of added exception handling optimizations.
https://blogs.msdn.microsoft.com/visualstudioalm/2016/02/12/using-the-debuggernonusercode-attribute-in-visual-studio-2015/#
There is a workaround posted on that link to disable the optimizations and enable the old behavior. Hopefully they will eventually be able to revive the support for this including the optimizations.
reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1
Related question:
Don't stop debugger at THAT exception when it's thrown and caught
Here's a code reproducing the behavior I'm expecting to get:
static void Main(string[] args)
{
// try // #2
{
string x = null; // #1
AssertNotNull(x, nameof(x));
}
// catch (ArgumentNullException) { } // #2
Console.WriteLine("Passed.");
Console.ReadKey();
}
[DebuggerHidden]
public static void AssertNotNull<T>(T arg, string argName) where T : class
{
if (arg == null)
throw new ArgumentNullException(argName);
}
The behavior is the same for any VS starting from VS2008 (did not check on earlier versions).
If you run it under debug (using a standard debugging settings) you're not allowed to continue until you fix the code (using the EnC). Hitting F5 will just rerun assertion due to [DebuggerHidden] and "Unwind stack on unhandled exception" setting combo (setting is enabled by default).
To fix the code, just replace the #1 line with object x = "", set the next statement to it and hit F5 again.
Now, enable "break when thrown" for the ArgumentNullException and uncomment the lines marked with #2.
The behavior changes: you're stopped on assertion again, but the stack does not unwind (easy to check with CallStack window). F5 will continue from the place the exception was thrown.
Ok, so... now the question is:
Is there any way to enable auto stack unwinding when breaking on handled exceptions?
Hidden VS option, existing extension or (maybe) API that can be used from my own extension?
UPD: To clarify the question: I want to break at the line with failed assertion, edit the code with edit and continue, set next statement to the fixed code and continue the execution.
As it works if the exception is not caught down the stack.
UPD2 As proposed by Hans Passant: Posted an suggestion on UserVoice. Feel free to vote:)
and uncomment the lines marked with #2
This is the critical part of your question. You changed more than one thing, the critical change is that you altered the way the stack is unwound. The debugger option you like is titled "Unwind stack on unhandled exception". Problem is, there is no unhandled exception anymore. Your catch clause handles it and it is now the CLR that unwinds the stack.
And it must be the CLR that does the unwinding, the debugger does not have an option to do it on the first-chance exception break that you asked for. And SetNext can't work at that point. Which, if I interpret the question correctly, you would really like to have since what you need to do next is busy work, single stepping through the catch block is not enormous joy.
Although it is not implemented, I think it is technically do-able. But only because I'm blissfully unaware how much work the debugger team will have to do. It is a good ask to make E+C work better, you can propose it here. Post the URL to your proposal as a commnent and good odds it will get a bunch of votes. I'll vote for it.
To clarify the question: I want to break at the line with failed
assertion, edit the code with edit and continue, set next statement to
the fixed code and continue the execution.
Open the "Exception Settings" Menu (Debug > Windows > Exception Settings)
Under "Common Language Runtime Exceptions", check the box for "System.ArgumentNullException". (Or check them all, whatever you're looking for.)
It should now break whenever a System.ArgumentNullException is thrown, regardless if it will be caught in a catch block.
However, you cannot edit and continue active statements. If you try to modify your assertion line, you'll see something like this:
I've got something like this:
try
{
instance.SometimesThrowAnUnavoidableException(); // Visual Studio pauses the execution here due to the CustomException and I want to prevent that.
}
catch (CustomException exc)
{
// Handle an exception and go on.
}
anotherObject.AlsoThrowsCustomException(); // Here I want VS to catch the CustomException.
In another part of code I have multiple occurencies of situations where CustomException is thrown. I would like to force the Visual Studio to stop breaking on instance.SometimesThrowAnUnavoidableException() line cause it obscures the view of other places where I'm interested in breaking on CustomException.
I tried DebuggerNonUserCode but it is for a different purpose.
How to disable Visual Studio from catching particular exception only in a certain method?
You can use custom code to do this in two steps.
Disable automatic breaking on the CustomException exception.
Add a handler for the AppDomain.FirstChanceException event to your application. In the handler, if the actual exception is a CustomException, check the call stack to see if you actually want to break.
Use the Debugger.Break(); to cause Visual Studio to stop.
Here is some example code:
private void ListenForEvents()
{
AppDomain.CurrentDomain.FirstChanceException += HandleFirstChanceException;
}
private void HandleFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Exception ex = e.Exception as CustomException;
if (ex == null)
return;
// option 1
if (ex.TargetSite.Name == "SometimesThrowAnUnavoidableException")
return;
// option 2
if (ex.StackTrace.Contains("SometimesThrowAnUnavoidableException"))
return;
// examine ex if you hit this line
Debugger.Break();
}
In Visual Studio, go to debug->exceptions and turn off breaking for your CustomException by unchecking the appropriate checkbox, then set a breakpoint in the code (probably on the catch statement) on the places you actually want to break on.
If you want Visual Studio to stop breaking on all exceptions of a type, you have to configure the behavior from the Exceptions window.
Full instructions are here, but the gist is to go to the Debug menu and choose exceptions, then uncheck the items you dont want the debugger to break on.
I don't think there is a way to avoid a specific method using this technique, but maybe the better question is "why is this throwing an exception?"
You could add a set of #IF DEBUG pre-processor instructions to avoid running the problematic sections of code.
You can disable stepping altogether by placing the DebuggerStepThrough Attribute before the method.
As this disables stepping in the whole method, you may isolate the try-catch into a seperate one for debugging purposes.
I did not test, but it should not even break in that method when en exception is thrown. Give it try ;-)
See also this SO thread
You can't simply disable Visual Studio from stoping in a particular place of code. You can only prevent it to stop when particular type of exception is thrown but that will affect all places where such exception occurs.
Actually you can implement custom solution as suggested by 280Z28.
I want to be able to break on Exceptions when debugging... like in Visual Studio 2008's Menu Debug/Exception Dialog, except my program has many valid exceptions before I get to the bit I wish to debug.
So instead of manually enabling and disabling it using the dialog every time is it possible to do it automatically with a #pragma or some other method so it only happens in a specific piece of code?
The only way to do something close to this is by putting the DebuggerNonUserCodeAttribute on your method.
This will ensure any exceptions in the marked method will not cause a break on exception.
Good explanation of it here...
This is an attribute that you put against a method to tell the debugger "Nothing to do with me guv'. Ain't my code!". The gullible debugger will believe you, and won't break in that method: using the attribute makes the debugger skip the method altogether, even when you're stepping through code; exceptions that occur, and are then caught within the method won't break into the debugger. It will treat it as if it were a call to a Framework assembly, and should an exception go unhandled, it will be reported one level up the call stack, in the code that called the method.
Code example:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
What about conditional breakpoints? If I understand correctly, you can have a breakpoint fire only when the value of a certain variable or expression is true.
Wrap your try catch blocks in #if DEBUG
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
I like to keep the curly braces outside of the #if that way it keeps the code in the same scope if inside or outside of debug.
If you still want the execption handeling but want more detail you can do this
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
This is a bit of too late for you, but this is the biggest reason I often try to teach people to use exceptions conservatively. Only use exceptions when something catastrophic has happened and your ability to reasonably continue is gone.
When debugging a program I often flip on First Chance Exceptions (Debug -> Exceptions) to debug an application. If there are a lot of exceptions happening it's very difficult to find where something has gone "wrong".
Also, it leads to some anti-patterns like the infamous "catch throw" and obfuscates the real problems. For more information on that see a blog post I made on the subject.
In terms of your problem, you can turn on first chance debugging for only a specific type of exception. This should work well unless the other exceptions are of the same type.
You could also use asserts instead of breakpoints. For instance, if you only want to breakpoint on the 5th iteration of a loop on the second time you call that function, you could do:
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
So in the first call to Work, while breakLoop is false, the loop will run through without asserting, the second time through the loop will break.
I have a statement inside a try/catch block, but the exception is not getting caught. Can anyone explain?
Exception Details:
System.NullReferenceException: Object
reference not set to an instance of an
object.
Source Error:
Line 139: try
Line 140: {
Line 141: return (int)Session["SelectedLeadID"];
Line 142: }
Line 143: catch (Exception ex)
Update
This is an ASP.NET application. In the catch block, a new exception is thrown. The code you see is what is displayed on the ASP.NET error page.
That catch block should catch the exception, but make sure there's no re-throwing in there.
Another small comment: I've been tricked quite a few times by VS, cause it breaks on exceptions like that while running in debug-mode. Try to simply press 'continue' or 'F5' and see if your application doesn't work anyway :)
I suspect you're going to need to add more detail - that isn't reproducible just from your code. In particular (as already noted) we'd need to see inside the catch, and verify that the exception is actually being thrown from inside the try and not somewhere else.
Other possibilities:
you have dodgy code inside the exception handler that is itself throwing an exception
you have a dodgy Dispose() that is getting called (using etc)
you are in .NET 1.1 and the thing getting thrown (in code not shown) isn't an Exception, but some other object
If it is only the debugger breaking on the exception and you are using VS2005 or above, you might want to check under Debug->Exceptions... if any of the Common-Language-Runtime-Exceptions are activated. If so, the debugger will always catch the exceptions first, but you are allowed to continue.
To revert to normal execution, simply uncheck the apropriate exceptions from the list.
I also faced this problem
Image
which was solved by removing the tick of
"Break when this exception type is thrown."
Warning:
Of course, I am not aware of the consequences of this.
I've also had such an issue and it was driving me nuts for quite some time, but in the end I figured it out. It's quite stupid, but maybe it might help someone:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter"), "SecondParameter"); //comma placed in the wrong spot
}
catch (Exception ex)
{
//some code
}
}
It should have looked like:
public IActionResult SomeFunction()
{
try
{
return Json(new ClassWhichTakes2Parameters("FirstParameter", "SecondParameter"));
}
catch (Exception ex)
{
//some code
}
}
Since I had many return statements in that function I didn't catch this right away.
Also, the error message I've been receiving wasn't quite what I have expected at first, but now it makes sense:
System.InvalidOperationException: Property
'JsonResult.SerializerSettings' must be an instance of type
'Newtonsoft.Json.JsonSerializerSettings'.
The code looks terribly ugly IMO. For there to be something in the catch() block means you are going to have another return ... statement which AFAIK you should always have a single return statement at the end of each function to make following code easier.
i.e. maybe your code should look like
public int Function()
{
int leadID = 0;
try
{
int leadID = (int)Session["SelectedLeadID"];
}
catch (Exception ex)
{
...
}
return leadID
}
Single exit points are supposed to make the code easier to follow, I guess? Anyway, to get any useful help you have to post more of the function.