Why doesn't the catch statement catch all the exceptions? [duplicate] - c#

This question already has answers here:
How to handle exception raised in linq
(2 answers)
Closed 6 years ago.
I'm testing the method below and I realized that when I enter wrong file name, the error gets caught but when I don't have an element on the position specified, the error of IndexOutOfBounds crashes the program. The latter goes also for converting errors.
private static IEnumerable<Thing> Initialize()
{
try
{
string[] things = System.IO.File.ReadAllLines("things.txt");
return things.Select(_ => new Thing
{
Name = _.Split(';')[0],
Id = Convert.ToInt32(_.Split(';')[0])
});
}
catch(Exception exception)
{
Console.WriteLine(exception.Message);
return new List<Thing>();
}
}
Why doesn't some errors get handled despite the most general Exception type in the catch? Does it have to do with LINQ expression failing? If so, how do I force the catching, then?

This is because you return IEnumerable.
The lambda inside Select doesn't execute immediately, but only on accessing the enumerable (iterating items).
If you add call "ToArray" after "Select" then all items will be calculated and IndexOutRangeException will be catched in your catch block.
return things.Select(_ => new Thing
{
Name = _.Split(';')[0],
Id = Convert.ToInt32(_.Split(';')[0])
}).ToArray();

You are returning an IEnumerable<> which implies deferred execution.
So anything inside the lambda is actually executing later, outside the try/catch.
If you want to catch all errors, include a .ToList() , like
return things.Select(...).ToList();

I have experienced this a couple of years ago, and the explanation I found online is that it is because of unmanaged assemblies and code. Something that is out of the application domain. Mostly when you have a lower level (os level) operation

Related

Write custom function that will happens when throw happened [duplicate]

This question already has answers here:
Custom exception handler
(5 answers)
Closed 5 years ago.
Is there a possibility to write a custom function that happened every time that throw of exeption happend without to write try and catch in c#?
UPDATE
I Want to get the exeption in my function and I'll check the exeption.
If I write try and catch, the catch will catch the exeption.
But I dont wont that there will be cases that the page will break Because there will not be try and catch.
In such cases I want to go to the base function.
Either some sort of product like Post Sharp (I think), or something a bit more invasive. Every call can be wrapped in an anonymous function that handles all exceptions for you. Then you can do whatever you want in that handler. Though, this requires you apply that style to all public methods that you'd want to deal with that issue.
Example:
public string GetSomeData() {
return Run(() => { ...some code... return "my result"; });
}
in the Run method, you can handle all try catch or whatever.

Catch block never firing inside a LINQ statement

I have some data I am deserializing inside a Linq statement:
var scheduledData = results
.Where(o => o.Result.IsValid)
.SelectMany(o => JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response))
.ToList();
This is throwing an error. I never see this error in the debugger. The returned web page lists a 500 error showing this. So I added some handing:
var scheduledData = results
.Where(o => o.Result.IsValid)
.SelectMany(o => {
try {
return JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response);
}
catch {
return new List<CalendarJob>();
}
})
.ToList();
Yes this is really ugly. I only did this so I could put a breakpoint on the catch block so I could inspect some values. This is not code I would leave in place! :)
I put a breakpoint on the return statement inside the try block and also the catch block. Then I execute the code. The try statement hits and execution is gone. The catch block never fires nor does any other code in my method.
Should this catch block be allowed in linq? I sure thought so?
Yes, I am in debug mode. Yes, I have cleaned and rebuilt. The breakpoint on my try block does indeed hit. I can inspect the value of the string about to be deserialized and the value is not right. It's "". I do not mean string.Empty, I specifically mean the string contains two bytes and both are the double quote character. The service I am getting the data from is not returning good data. But my catch block never fires.
One more thing to note. I put the entire thing into a try...catch block and that catch block does hit. Only the one inside LINQ does not.
Yes - this will work the way you think it will.
The only time it won't work will be an exception you cannot catch, like a StackOverflowException.
To prove it, just execute the folllowing code in Visual Studio, or Linqpad and observe the breakpoint is hit twice.
var list = new List<string>
{
"a",
"b"
};
list.Select(i =>
{
try
{
return int.Parse(i);
}
catch
{
return 0; // Put a breakpoint here.
}
}).ToList();
I found the cause. Internally JsonConvert doesn't throw an error with invalid Json. Instead it returns null. So my try...catch block around the JsonConvert didn't do anything because there was nothing to catch. Next, SelectMany was expecting a List<> item back and tried to enumerate it to select the elements out of it. Because it received null, the error was thrown here and not inside the Json conversion. This is why the outer try...catch picks up the error but the one in the OP above does not.
I accepted RB's answer because he answers my original question. This is simply an explanation for any future finders.

Exception Handling - What is the correct way to do it? [duplicate]

This question already has answers here:
General Exception Handling Strategy for .NET
(11 answers)
Closed 9 years ago.
I have been using exception handling for some time and have installed Resharper and now getting all sorts of messages saying I should and should be doing this. Anyway, it says I shouldn't be using try and catch blocks around my code. So where do I put them to catch exceptions? I have seen people looking for certain exceptions like File not found, but what about all the other errors or exceptions that are unique?
Here's an example of some exception handling it moans about:
try
{
var rnd = new Random();
var buffer = new byte[sizeof(UInt64)];
rnd.NextBytes(buffer);
}
catch (Exception)
{
throw;
}
Does anyone have links for best practices for exception handling that would keep re-sharper happy?
Only catch those exception which you can handle, like insertion of duplicate primary key, So that you can show the user a message to enter different values.
For other exception let them bubble up in your library and handle them in one place. Like Application_Error event in ASP.Net
As pointed out by others already, only use try/catch if you actually plan to do something about the exception inside the catch block - doing so keep in mind that there is actually no guarantee that the catch block will actually execute (e.g. a power failure).
See explanation that was given to me when I asked a quite similar question: when to use try/catch
If you only wish to diagnose/log an exception and don't do anything specific about it, you can use a global exception handler, i.e. AppDomain.UnhandledException - this way you can centralize handling.

Why do I get "Sequence contains no elements"?

NOTE: see edits at bottom. I am an idiot.
I had the following code to process set of tag names and identify/process new ones:
IEnumberable<string> tagNames = GetTagNames();
List<Tag> allTags = GetAllTags();
var newTagNames = tagNames.Where(n => !allTags.Any(t => t.Name == n));
foreach (var tagName in newTagNames)
{
// ...
}
...and this worked fine, except that it failed to deal with cases where there's a tag called "Foo" and the list contains "foo". In other words, it wasn't doing a case-insensitive comparison.
I changed the test to use a case-insensitive comparison, as follows:
var newTagNames = tagNames.Where(n => !allTags.Any(t => t.Name.Equals(n, StringComparison.InvariantCultureIgnoreCase)));
... and suddenly I get an exception thrown when the foreach runs (and calls MoveNext on) newTagNames. The exception says:
Sequence has no elements
I'm confused by this. Why would foreach insist on the sequence being non-empty? I'd expect to see that error if I was calling First(), but not when using foreach?
EDIT: more info.
This is getting weirder by the minute. Because my code is in an async method, and I'm superstitious, I decided that there was too much "distance" between the point at which the exception is raised, and the point at which it's caught and reported. So, I put a try/catch around the offending code, in the hope of verifying that the exception being thrown really was what I thought it was.
So now I can step through in the debugger to the foreach line, I can verify that the sequence is empty, and I can step right up to the bit where the debugger highlights the word "in". One more step, and I'm in my exception handler.
But, not the exception handler I just added, no! It lands in my outermost exception handler, without visiting my recently-added one! It doesn't match catch (Exception ex) and nor does it match a plain catch. (I did also put in a finally, and verified that it does visit that on the way out).
I've always taken it on faith that an Exception handler such as those would catch any exception. I'm scared now. I need an adult.
EDIT 2:
OK, so um, false alarm... The exception was not being caught by my local try/catch simply because it was not being raised by the code I thought. As I said above, I watched the execution in the debugger jump from the "in" of the foreach straight to the outer exception handler, hence my (wrong) assumption that that was where the error lay. However, with the empty enumeration, that was simply the last statement executed within the function, and for some reason the debugger did not show me the step out of the function or the execution of the next statement at the point of call - which was in fact the one causing the error.
Apologies to all those who responded, and if you would like to create an answer saying that I am an idoit, I will gladly accept it. That is, if I ever show my face on SO again...
It's not as proper or clean, but how does this work:
var newTagNames = tagNames.Where(n => !allTags.Any(t => t.Name.ToUpper() == n.ToUpper()));
Exception handling is fun on deferred actions. The Enumerable.Where method (and most linq methods) are not executed until the query is enumerated.
IEnumerable<int> query = Enumerable.Empty<int>();
int myNum = 0;
try
{
query = Enumerable.Range(1, 100).Where(i => (i/myNum) > 1);
}
catch
{
Console.WriteLine("I caught divide by zero"); //does not run
}
foreach(int i in query) //divide by zero exception thrown
{
//..
}
In your particular case:
IEnumberable<string> tagNames = GetTagNames();
I bet GetTagNames has a Enumerable.First or Enumerable.Single inside there somewhere. If the result of GetTagNames is deferred, you must enumerate that result to get the exception to occur. That is why the commenters are recommending you call ToList on the result of GetTagNames - to enumerate it and get the exception to occur before your use of tagNames in a complicated query.

Is there a standard .NET way to test if a SqlConnection string works? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to check if connection string is valid?
Currently I'm doing it like this:
internal bool CheckConnection()
{
using (SqlConnection testConn = new SqlConnection(this.ConnectionString))
{
try
{
testConn.Open();
}
catch (SqlException)
{
return false;
}
}
return true;
}
Is there a better way to do this?
That is pretty much the way to do it. Though you should think about handling some other exception types as well. There can be other reasons why you don't connect to a db server besides a sql issue.
Connection.Open can throw InvalidOperationException and ArgumentException in addition to SqlException. Also the APIs that .Open calls can throw other types of exceptions that can percolate to your code as well. In fact, this is one of the rare instances when it might be preferable to handle the base exception and display its message to the user. (The general rule of thumb is to handle only the specific exceptions.)
Nop, there's not... that's the only way
What you can is catching the SqlException and return a little more info inc ase of fail depending on the Number in the exception

Categories

Resources