I'm using Microsoft.VisualStudio.TestTools.UnitTesting for unit testing.
I have this test which asserts that an exception was thrown and it is failing
[TestMethod]
public async Task ShouldThrowHttpExceptionIfPassedObjectIsNull()
{
_mockLogger = new Mock<ILogger<DataService>>();
// setup memoryCache
object expected = null;
_mockNullMemoryCache = MockMemoryCacheService.GetNullMemoryCache(expected);
_mockSessionManagementService = new MockSessionManagementService();
_ds = new DataService(
_mockLogger.Object,
_mockNullMemoryCache.Object,
_mockSessionManagementService
);
Assert.ThrowsException<HttpException>(() => _ds.RetrieveFileData<object>(_incorrectFilePath, false));
}
When I debug it, the last line of code to run before it errors out and fails is this:
The exception ex is a system.invalidOperationException but that shouldn't matter because it throws an HttpException not matter what. Why is the test failing with the reason:
Test Name: ShouldThrowHttpExceptionIfPassedObjectIsNull Test
FullName: xxx.xxx.xxx.xxx.ShouldThrowHttpExceptionIfPassedObjectIsNull
Test
Source: C:\Users\xxx\xxx.cs
: line 88 Test Outcome: Failed Test Duration: 0:04:35.5251661
Result StackTrace: at
xxxxxx.d__10.MoveNext()
in
C:\Users\xxx\xxx\xxx.cs:line
101
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) Result Message: Assert.ThrowsException failed. No exception
thrown. HttpException exception was expected.
EDIT
The code then moves into this code block after the image:
else
{
// Parsing issue
_logger.LogError(string.Format("Id={0}, Could not retrieve data from {1} : Malformed source data", _sessionManagementService.SessionId, url));
throw new HttpException(HttpStatusCode.InternalServerError, "Malformed source data", true);
}
As it is throwing the HttpException above, it throws a DllNotFoundException.
Exception thrown: 'System.DllNotFoundException' in
System.Private.CoreLib.ni.dll
Additional information: Unable to load DLL 'combase.dll': The
specified module could not be found. (Exception from HRESULT:
0x8007007E)
When I look at the type hierarchy of HttpException, I see that it doe not inherit from InvalidOperationException. Therefore the unit test fails correctly.
Likely there's some LINQ code or other code which cannot execute correctly, therefore catches the HttpException and converts it into the InvalidOperationException.
You should be able to debug the unit test. Instruct Visual Studio to stop at exceptions, then go forward step by step and try to find out where your exception gets converted, e.g. when you step through some LINQ code.
The MoveNext() call indicates that something tries to loop over values. When debugging, disable Just my code, because it could be in the .NET framework.
Related
I was hoping somebody could enlighten me a little bit on an issue I am facing in regards to async/await exception handling with HttpClient. I have written some code to illustrate, and it is being excecuted on both a Windows Phone 8 device and the emulator:
private async void SearchButton_Click(object sender, EventArgs e)
{
try
{
HttpClient client = new HttpClient();
System.Diagnostics.Debug.WriteLine("BEGIN FAULTY REQUEST:");
string response = await client.GetStringAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/");
System.Diagnostics.Debug.WriteLine("SUCCESS:");
System.Diagnostics.Debug.WriteLine(response);
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine("CAUGHT EXCEPTION:");
System.Diagnostics.Debug.WriteLine(exception);
}
}
Tapping the button that invokes this function, produces the following output in the debugger console, the most interesting being the ones in bold:
BEGIN FAULTY REQUEST:
An exception of type 'System.Net.WebException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
An exception of type 'System.Net.WebException' occurred in System.Windows.ni.dll and wasn't handled before a managed/native boundary
A first chance exception of type 'System.Net.Http.HttpRequestException' occurred in mscorlib.ni.dll
An exception of type 'System.Net.Http.HttpRequestException' occurred in mscorlib.ni.dll and wasn't handled before a managed/native boundary
CAUGHT EXCEPTION:
(and here it prints out the HttpRequestException)
Of course I am expecting an error in this case since the URL I am calling is nonsense. What I am not understanding here, is why the debugger reports that the exceptions are not handled, when the output simultaneously reports that the exception is caught. Also, the UI side of the app becomes much less responsive while the output is being printed, indicating that something is probably amiss.
Is this not the way to handle exceptions when working with async and await? I appreciate any input! Thanks.
As you are using HttpClient, try to use response.EnsureSuccessStatusCode();
Now HttpClient will throw exception when response status is not a success code.
try
{
HttpResponseMessage response = await client.GetAsync("http://www.ajshdgasjhdgajdhgasjhdgasjdhgasjdhgas.tk/");
response.EnsureSuccessStatusCode(); // Throw if not a success code.
// ...
}
catch (HttpRequestException e)
{
// Handle exception.
}
ORIGINAL SOURCE OF THE CODE: http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client
This is an artifact of the debugger. It's determining that an exception is "uncaught" because it's not caught yet. In this case this is expected behavior.
You are handling the exceptions correctly.
The debugger is telling you that this exception is first chance. When a debugger is attached to your process it gets notified for every exception that is thrown and then based on how the debugger has been configured it will decide what to do with it. You can go through What is first chance exception? for more details.
On a side note, catch specific exceptions only so that you understand which exceptions you are expecting and why.
I run into troubles using the Roslyn Scripting Engine. I get no exception handling when I run a script within a delegation.
Test that works as expected:
string script = #"var a=0; var b=2/a;";
var runner = CSharpScript.Create<object>(script);
var errors = runner.Compile();
Assert.IsTrue(errors.IsEmpty);
try
{
runner.RunAsync();
Assert.Fail("Where is the exception");
}
catch (System.Exception)
{
// everything is OK! Error thrown...
}
Result: No Assertion. The Exception was thrown.
Here's the text using a delegate object:
Unittest:
string script = #"var a=0; var b=2/a;";
var runner = CSharpScript.Create<object>(script);
var errors = runner.Compile();
var delegat = runner.CreateDelegate();
Assert.IsTrue(errors.IsEmpty);
try
{
delegat();
Assert.Fail("Where is the exception?");
}
catch (System.DivideByZeroException)
{
// everything is OK! Error thrown...
}
I got the fail message and no exception was thrown.
We cache the delegates to speed up the compilation and during a test we see that runtime exceptions are not thrown. So I wrote the test to reproduce this situation.
I can't find any hint in the docs which describes that there are no exceptions thrown during the invoke.
Can someone give me a pointer or a hint why this happens?
There are two issues with your code:
In the first version, you're catching Exception, which means that when the Assert.Fail is reached and throws AssertionException, that exception is then caught and ignored.
This means that there is no difference between RunAsync and delegate here, neither of them throws DivideByZeroException.
Both RunAsync and the ScriptRunner<T> delegate return Task. That means to actually wait for them to complete or to observe any exceptions, you need to use await. Once you do that, you will see the DivideByZeroException that you're expecting.
Your Main finishes execution before the scheduler gets a chance to invoke delegat. It is a task that will run asynchronously. You can see that when you inspect it in the debugger:
To force execution inside the scope of the try...catch, you can use this:
try
{
delegat().Wait();
}
catch(System.AggregateException ex)
{
/* the inner exception of ex will be your DivideByZeroException */
}
The correct type of exception to expect in this case is the AggregateException, see here why.
A solution with await is also possible:
await delegat();
but this will compile only when the containing method can be marked async which is not necessarily what you want (show more of the calling code to clarify).
I wrote windows 8.1 universal app (monogame/Windows8.1) in Visual Studio 2013 and try to catch stack trace of exception in draw thread. I added handlers to
CoreApplication.UnhandledErrorDetected
Application.Current.UnhandledException
TaskScheduler.UnobservedTaskException
AsyncSynchronizationContext.Register()
In project settings I set full debug info.
Now I have 2 problems: I get only one line of my call (and async garbage like MoveTo and Result()) and this line even doesn't have line numbers:
HRESULT: -2147024864
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at com.mytest.CBackground.d__0.MoveNext()
Stack above I get when throw exception in async method. If I throw exception in non-async method handler of Application gets full stack trace, but again without line numbers.
However if I write:
try
{
throw new Exception();
}
catch (Exception e)
{
s = e.Message + " " + e.StackTrace;
}
I get only one line - name of method where I threw that exception. Why?
How can I get line numbers?
Why there are no previous lines (calls from my code to my method com.mytest.CBackground.setupBootActions())?
Even if I launch with debugging from VS there is no line numbers when I break on exception.
I designed a program with Windows Forms Designer and added functionality that gets executed when pushing a certain Button. After executing my program and clicking on said button I get the following Error:
An unhandled exception of type 'System.ArgumentOutOfRangeException'
occurred in mscorlib.dll
Additional information: Index was out of range. Must be non-negative and less than the size of the collection.
The weird part is that it tells me the error happens when I call the method; as in:
private void btPPTX_Click(object sender, EventArgs e)
{
PptxConverter.Generate();
}
I had the same error before but it showed me the exact line where it was happening(Inside of the Generate-Method). I corrected my error but now I don't even know where to start looking. The Generate-Method is very extensive and involves a whole set of other methods so it's tough to find the error or post the whole code here.
Is there any effective way to find the error or do I have to go through the code line by line to find it?
I'm using Visual Studio Community 2015
The StackTrace is one of your ways to investigate exception in a method graph (nested calls):
try
{
PptxConverter.Generate();
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
When you print the exception object, you get the exception message and the stack trace which is a detailed call hierarchy that leads you to the exact Method(with line number sometimes) where the last exception was thrown.
Given a method Main that calls A that calls B that calls C (which throws the exception) Stack-trace looks like this:
/*
System.Exception: Some Error Message
at ProjectName.Program.C() in C:\Users\User\Documents\Visual Studio 2015\Proj
ects\ProjectName\ProjectName\Program.cs:line 87
at ProjectName.Program.B() in C:\Users\User\Documents\Visual Studio 2015\Proj
ects\ProjectName\ProjectName\Program.cs:line 82
at ProjectName.Program.A() in C:\Users\User\Documents\Visual Studio 2015\Proj
ects\ProjectName\ProjectName\Program.cs:line 77
at ConsoleTest.Program.Main(String[] args) in C:\Users\User\Documents\Visual
Studio 2015\Projects\ProjectName\ProjectName\Program.cs:line 52
*/
I'm receiving an unhandled exception while debugging, and the program stops executing. The debugger doesn't show me the line so I don't know what to fix.
An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll
Additional information: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
Cannot obtain value of local or argument '<this>' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Threading.Tasks.TaskExceptionHolder
How can I troubleshoot this problem?
I also found this question which is pretty similar.
As the message says, you have a task which threw an unhandled exception.
Turn on Break on All Exceptions (Debug, Exceptions) and rerun the program.
This will show you the original exception when it was thrown in the first place.
(comment appended): In VS2015 (or above). Select Debug > Options > Debugging > General and unselect the "Enable Just My Code" option.
You could handle the exception directly so it would not crash your program (catching the AggregateException). You could also look at the Inner Exception, this will give you a more detailed explanation of what went wrong:
try {
// your code
} catch (AggregateException e) {
}
The accepted answer will work if you can easily reproduce the issue. However, as a matter of best practice, you should be catching any exceptions (and logging) that are executed within a task. Otherwise, your application will crash if anything unexpected occurs within the task.
Task.Factory.StartNew(x=>
throw new Exception("I didn't account for this");
)
However, if we do this, at least the application does not crash.
Task.Factory.StartNew(x=>
try {
throw new Exception("I didn't account for this");
}
catch(Exception ex) {
//Log ex
}
)
In my case I ran on this problem while using Edge.js — all the problem was a JavaScript syntax error inside a C# Edge.js function definition.