Should I throw a KeyNotFoundException for a database lookup? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've got some code that, given an ID, returns an item from the database. If no item matches the given ID, is it appropriate to throw a KeyNotFoundException, or are such exceptions meant only for Dictionary types?

Depending on the framework you're using to access the database (ODBC, ADO.NET, etc.) there's likely a better alternative that the framework would throw.
The System.Data namespace contains several such exceptions as examples: http://msdn.microsoft.com/library/system.data.
Really, though, as long as you document what exception you're throwing and in what conditions it doesn't matter too much. Using something common is best because people may assume, but if they are reading documentation they will handle whatever exception you say would be thrown.

The MSDN page for KeyNotFoundException states:
The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.
Semantically a KeyNotFoundException would be appropriate. Just make sure your error message is descriptive enough to actually help when debugging. Also, remember that you lose any contextual type information that using a custom exception type would give you.
A custom exception type gives you the ability to differentiate between the two conditions using general C# idioms, like so:
try
{
// do some database stuff
}
catch(KeyNotFoundException e)
{
// Here you know that it was more than likely caused by a Dictionary
// or some such collection
}
catch(DatabaseKeyNotFoundException e)
{
// Here you know that it was caused by a DB record not being found
}
Whichever you choose, just make sure you think about it, that it's consistent and logical. Don't just choose one because it's easier.

MSDN says yes* (if you consider a database table a collection) -
The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.
Why not just return false or some other indication that the value was not in the database?

Related

SaveChangesAsync returns exception instead of 0 [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
About SaveChangesAsync method, Microsoft says
it's a task that represents the asynchronous save operation. The task result contains the number of state entries written to the underlying database.
According to that, some programmers use if condition to check the number of rows affected after SaveChangesAsync is run.
Here is an example: How can I confirm if an async EF6 await db.SaveChangesAsync() worked as expected?
But, what happens if an error occurs when calling SaveChangesAsync? Well, contrary to what I expected, which would be "0 lines affected", an exception is thrown, in most cases, a DbUpdateException
"Exception thrown by DbContext when the saving of changes to the database fails."
So, why are there several recommendations for using if (await context.SaveChangesAsync() > 0) once the result from database will never be zero, but instead, an exception?
So, why are there several recommendations for using if (await context.SaveChangesAsync() > 0) once the result from database will never be zero, but instead, an exception?
First off, there are no such official recommendations. The people who provided them have no idea of the semantics of the SaveChanges operation. Which by current official EF Core documentation is:
Returns
Int32
The number of state entries written to the database.
Exceptions
DbUpdateException
An error is encountered while saving to the database.
DbUpdateConcurrencyException
A concurrency violation is encountered while saving to the database. A concurrency violation occurs when an unexpected number of rows are affected during save. This is usually because the data in the database has been modified since it was loaded into memory.
This is for SaveChanges, but the same is for Async version after awaiting it.
So, as it can be seen from the docs, the operation can return 0 and still be successful. It's because the smart update (load/modify/save) might not generate database operation. But still it is saved - because you don't ask "please force write this to database", but "please make sure this data is saved to the database". It's true that if you perform perform forced update, then 0 is never returned. But that's not essential at all.
The more important is, the success of the operation is determined as usual by the lack of exception. I don't know what is the intended usage of the return value - it might be just because it is something "we can return". Or carry over from EF6 which in turn is carry over from ADO.NET etc. Or just use it for some logging if real database CUD occurred. Who knows. But, for sure one should not use it for checking the success as in these (anti) "recommendations".

Is it a bad idea return a tuple instead of throw an exception? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have a method, that always has to return an object of type MyType. If it returns null it is because I don't have the needed information to return a value.
So I was thinking that a posibility it is to throw an argument exception if I don't have the needed information.
Another solution, it is to return a tuple, first item null or the object as result. The second item a string, null if I can return the value or a string with the reason why it is null.
I was consideration this second option, because I guess it is more versatile, who calls this method, if get a null, can know the reason of why it is null and don't need to handle the exception, that requieres more code. Also, if it is called in the UI layer, it can tell the user what information it is needed.
An exception it is more expensive if it is thrown, and also, from a point of view, I considerate the exception the way to handle something that I can't control in another way, but in this case I can know in advance if I have the needed information or not from the user, so it is not something unexpected like if I try to load a file and the file doesn't exist, for example, or try to connect to a network resource and the network is down.
Also, argument exception it is a generic exception, if I want to show to a user a understanding message but also I want a more detailed message for the developer, it is more complex code.
So I was wondering if really it is a bad idea to return a tuple or it is better to throw an exception.
I think a touple can be very usefull, because it can return the value of the method, but also can provide aditional information in another items.
This is a variant on the Return codes vs exception discussion.
I would recommend using a specialized type rather than just a plain tuple. This should either have a value, or a string/error code. This should force the caller to handle at least one case, for example by having OnSuccess(Action<T>) and OnFail(Action<string) methods. See Result of T for an example
If this is preferable to exceptions somewhat depend on if failure is expected or not. I think it is appropriate for something like a Parse-method. For reading a file I would prefer exceptions since reading the file can fail at any time for many possible reasons. I.e. a result object fits best with a functional style.

LINQ: Why use ...Take(1).SingleOrDefault()? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm currently examining some code I'm going to maintain.
I see a few occasions of
.Take(1).SingleOrDefault()
Why would you use that instead of simply
.First() or .FirstOrDefault()
(I'm not sure whether .Take(1) would throw an exeption if the result set is empty, which imho would make the difference between the two .First... Methods?)
It is impossible for us to know for sure the inner implementation of whatever LINQ provider you may be using. They all vary in how they do it. Some may be more performant in cases like this whereas others may be less performant. You should get the same result either way.
It is not possible for us to read someones mind to determine why they would have done it this way in this case.
With that said, if you want to dig in deeper and it is a SQL provider, you can see what SQL it generates and compare the two cases.
The main objection is that .Take(1).SingleOrDefault() defeats the purpose of SingleOrDefault, which is to throw an exception when the LINQ query returns more than one element.
To illustrate this, when running LINQ against a Sql Server backend Single(OrDefault) will translate into SELECT TOP (2) ... in order to determine whether there actually is one record. Preceding this by Take(1) will never return more than one record, so the "multiple result" exception will never occur although the code seems to require it. This code looks like a (premature) optimization by someone who's worried about returning two objects instead of one.
So the answer to your question "Why would you use that?" is: there's absolutely no reason to do it this way. There are only reasons not to do it.

Try-Catch Exception abuse [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have found some code like this:
try
{
myClass.do().ToString();
} catch () { }
which certainly results in an exception being thrown when do() returns null. You could, instead, use
(myClass.do() ?? "").ToString();
to avoid the exception being thrown. I also see code like this:
for (int i = 0; i < x.length; i++)
{
if (x.Phases[i].num == activeNum)
{
try
{
result = x.Phases[i + 1].obj;
}
catch (Exception ex) { }
}
}
I think that this is not good practice. However, I can't find any references to support my ideas.
I tried to search on web, but I did not have any luck. Most of the references or documentation was meant for C++ or Java.
Will you please help me to justify my idea with strong reference, or enlighten me if the previous approaches above are in fact acceptable.
You're correct: using exceptions for purposes of flow control is generally bad practice. It is often referred to as an anti-pattern for this reason.
You can find a detailed explanation here. While the article references Java and C++, it is also an anti-pattern in C# for much the same reasons.
For a C#/.Net specific explanation, see this MSDN article.
Your intuition is right. Exception handling is slow.
Branching (such as an underlying jump when the for-loop terminates) is very fast.
Don't waste your time on exception handling as a means of flow control.
EDIT:
Note that there is ample evidence for such claims, and that for instance, you may reference the Wikipedia article on the subject for an explicit indication that flow control is not the intended role of exception handling code in C#.

C#: Article about throwing proper type of exception [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Sometimes I dont know witch type of exception should I throw. So I usually throw Exception(). Is there some nice article about this?
The problem with throwing a generic exception is that it restricts the ability of your code further up the stack to handle it properly (i.e. best practice is to trap the most specific exception possible before falling back, and to only capture what you can handle).
Jeffrey Richter has an excellent section on exception handling (including info on the System.Exception namespace) in CLR via C#
"Framework Design Guidelines" by Cwalina and Abrahms covers this topic really well (IMHO).
It is available for free online here, or the book (not free) here (UK) or here(US). Look in the section entitled Design Guidelines for Exceptions.
If you are not making any attempt to recover from an error, you can just throw an Exception with a string to tell you what went wrong. (Or if you will perform the same action regardless of what error occurred).
Other than making it obvious to a programmer what went wrong by using a new exception name rather than putting it in the Message, and exception can contain data to help you recover from a particular exception.
For example, an ArgumentNullException has a property ParamName, which you should set when you throw the exception. When the caller catches it, he can then look up this property and decide to pass a new value for the argument which caused the error, or can print a relevant error to inform the programmer what went wrong.
It's unfortunate that exceptions are rarely used to their full potential (in many open source APIs and such), and are often simply inserted to inform a programmer what went wrong. There's not much difference between these 2 if you don't plan to read the ParamName property when you catch it. (Many people will not bother, and only catch an Exception anyway).
throw new ArgumentNullException("arg1");
throw new Exception("arg1 is null");
It can be difficult to recover from an error fully, but in some applications though, you might find it desirable to create custom exceptions which can provide all the details you need.
For now, I would just put Exception into the Object browser search in VS, and see what is there already. Their names are pretty self explanatory, so you should be able to pick out something suitable.
Well, the one thing you shouldn't do is throw Exception itself.
Always look for an appropriate subclass.
I don't know of any publication spelling out which exception to throw when, but ArgumentException and InvalidOperationException should take care of most of your cases.
Ask separate questions about separate cases if they come up.
I would suggest dividing exceptions into a few categories based upon the system state:
The method failed in such a fashion that it did nothing; the state of any underlying data was not disturbed, and is probably valid. Typical scenarios: trying to retrieve from a collection an object which isn't there, or add one which already is. Another possible scenario: a communications timeout in cases where it should not have caused any data loss (and were retrying the operation might succeed if the problem was simply that the other end was simply too slow).
The method failed in a fashion which may have disturbed the underlying data structure, or the underlying data structure may have been corrupted previously. Further operations should not be attempted with this data structure unless steps are taken to validate it. Another possible scenario: a communications timeout occurs when a record has been partially retrieved, and the partially-retrieved data is now lost. Depending upon the protocol, it may be necessary to perform some recovery action on the connection, or to close it and initiate a new one.
Something is seriously wrong with the system state, and recovery is likely not possible.
Unfortunately, existing .net exceptions don't fit anything like that pattern; it would have been nice if there were a type ExceptionBase from which things like ThreadAbortException, CpuHasCaughtFireException, and the 'normal' Exception were derived, and all 'normal' exceptions were derived from Exception. I understand that .net 4.0 somewhat kludges in such a design, but I don't know the exact mechanics. In any case, I would suggest that any user-defined exceptions should be divided into groups as above, with all exceptions in each group sharing a common ancestor distinct from other groups.
There's an article by Krzysztof Cwalina ("a Principal Architect on the .NET Framework team at Microsoft") called Choosing the Right Type of Exception to Throw that sheds some light on this. It deals with choosing the right exception to throw and guidance on creating custom exceptions.

Categories