I'm confused as to the best way to try and deal with possible InvalidOperationException.
In my code, I get a blue line under (decimal)data.CurrencyExchangeRate so changing the code to:
data.CurrencyExchangeRate.GetValueOrDefault() removes the blue line.
As the data is from a database and the column is a decimal, it will never be null.
So is GetValueOrDefault the best way to deal with the possible error?
I'm just not sure how best to handle it.
Thanks
Assuming CurrencyExchangeRate is a nullable decimal, the GetValueOrDefault extension method is your safest bet - if you want to use a default of zero when the value is null.
For other default values, such as 1, use something like this:
decimal val = data.CurrencyExchangeRate.HasValue
? data.CurrencyExchangeRate.Value
: 1M;
The only exceptions you'll catch from GetValueOrDefault will be from the system such as OutOfMemoryExceptions etc. So it's unlikely you'll get an error here.
You should still use a try/catch. Never assume that the data from the database is always valid. For example, what if I changed the datatype in the database to be a VARCHAR and added a null value, your application would crash. Therefore it makes sense to handle the exception.
try {
var value = data.CurrencyExchangeRate.GetValueOrDefault();
} catch (InvalidOperationException e) {
// Log the exception
}
Related
Okay, I have some very simple code which I will post below. Essentially, I have a connection to a database and I want to map a subset of columns in a query to a particular class. The problem is that it is possible for these to be null.
I would like to know if it is possible if an exception is thrown at a particular line, can we resume the entire block from the next line.
So if this code below was to execute and Line 6 catches an error. Is there an elegant way to catch the exception and make the code resume running at line 7. Essentially making it as though line 6 was never executed.
private static Column MapTableToColumn(OracleDataReader reader){
Column c = new Column();
c.ColumnName = Convert.ToString(reader["COLUMN_NAME"]);
c.DataType = Convert.ToString(reader["DATA_TYPE"]);
c.DataLength = Convert.ToInt32(reader["DATA_LENGTH"]);
c.DataPrecision = Convert.ToInt32(reader["Data_Precision"]);//<---Line 6
c.DataScale = Convert.ToInt32(reader["Data_scale"]);//<--- Line 7
c.AllowDBNull = Convert.ToBoolean(reader["ALLOW_DB_NULL"]);
c.IsReadOnly = Convert.ToBoolean(reader["IS_READ_ONLY"]);
c.IsLong = Convert.ToBoolean(reader["IS_LONG"]);
c.IsKey = Convert.ToBoolean(reader["IS_KEY"]);
c.KeyType = Convert.ToString(reader["KEY_TYPE"]);
c.IsUnique = Convert.ToBoolean(reader["IS_UNIQUE"]);
c.Description = Convert.ToString(reader["DESCRIPTION"]);
return c;
}
It is important to note I am not asking for best practice, it is not something I intend to use in actual code (unless its absolutely genius). I simply want to know if this is possible and how one would go about doing this if it were.
My Research
Most of my research is proactive as opposed to reactive. I would attempt to know if it is possible for the given field to be null before it is read from. If it is, then I'd do a check to determine if the field is null and then set it to a default value. It essentially avoids the possibility of an error happening which I believe is a very good solution. I just wanted to attempt this as I know that when an exception is thrown, the most inner exception contains the line number at which it was thrown. Based on this if you put the exception inside of the class throwing the exception you should hypothetically be able to use reflection in order to continue running from its last point. I'm just not sure how you'd go about doing this. I've also considered the possibly of putting try catches around every single line which I think would be very effective; however, I think that it would be very ugly.
No, what you are asking for is not possible in C#.
Instead the proper solution to this problem is to use better parsing methods that won't throw exceptions in the first place. If your input values can be null, then use parsing methods that can accept null values.
The first thing you probably need to do is use nullable types for your int/bool fields, so that you can support null values. Next, you'll need to create your own methods for parsing your ints/bools. If your input is null, return null, if not, use int.TryParse, bool.TryParse (or as for each if your input is the proper type, just cast to object).
Then by using those methods, instead of Convert, you won't be throwing exceptions in the first place (which you shouldn't be doing here even if it could work, because exceptions are for exceptional cases, not expected control flow).
If the exception is expected then it is not exceptional. Never never never catch a null reference exception. A null reference exception is a bug. Instead, write code to avoid the bug.
You can easily write helper methods that test for null, or use methods like Int32.TryParse that can handle malformed strings.
Check for IsDBNull
SqlDataReader.IsDBNull Method
And Reader has methods for each SQL datatype
For example
SqlDataReader.GetSqlBoolean
If the data is in SQL as string (char,nchar) then first check for null and then TryParse
For example
DateTime.TryParse
And ordinal position is faster
This is a sample for a nullable Int16
Int16? ID;
ID = rdr.IsDBNull(4) ? (Int16?)null : rdr.GetInt16(4);
If you want a default
Int16 ID;
ID = rdr.IsDBNull(4) ? 0 : rdr.GetInt16(4);
You'd need a try/catch around every single variable assignment, and you'd need to initialize all your Column instance values before you tried. This would be relatively slow.
As for reflection based on the line number: I wouldn't rely on the line number because one simple, innocent change to the code will throw it off completely.
I'd check for nulls specifically. If you expect them you can't hardly call them "exceptions". The method that does that is reader.IsDBNull. It takes the column index (not the column name) so you'll need to resolve the index using reader.GetOrdinal:
if (reader.IsDBNull(reader.GetOrdinal("Data_Precision"))) {
// It's null
} else {
// It's not null
}
if you think there is a possibility of getting a null pointer exception, should you use an if statement to make sure the variable is not null, or should you just catch the exception?
I don't see any difference as you can put your logic to deal with the null pointer in the if statement, or in the catch block, so which one is best practise?
I would say ALWAYS use logic to catch the exception, not try/catch.
Try/Catch should be used when you validate but some strange thing happens and something causes an error so you can handle it more gracefully.
There is no single answer that will suffice here, it depends.
Let's take a few scenarios so you can see what I mean.
Scenario: Method that takes a reference type parameter that does not accept null
You're defining a method, it takes a reference type parameter, say a stream object, and you don't want to accept null as a legal input parameter.
In this case, I would say that the contract is that null is not a valid input. If some code does in fact call that method with a null reference, the contract is broken.
This is an exception, more specifically, it's an ArgumentNullException.
Example:
public void Write(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
...
I would definitely not just let the code execute until it tries to dereference the stream in this case, instead crashing with a NullReferenceException, because at that point I lost all ability to react when I know the cause.
Q. Why can't I return false instead of throwing an exception?
A. Because a return value is easy to silently ignore, do you really want your "Write" methods to just silently skip writing because you made a snafu in the calling code, passing the wrong stream object or something that cannot be written to? I wouldn't!
Scenario: Method returns a reference to an object, sometimes there is no object
In this case the contract is that null is a legal result. In my opinion, null is something to avoid because it is quite hard to make sure you handle correctly everywhere, but sometimes it is the best way.
In this case I would make sure to if my way around the result, to ensure I don't crash when the null reference comes back.
Generalisation
If you take a close look at the above two scenarios, you'll note one thing:
In both cases it comes down to what is being expected, what the contract is.
If the contract says "not null", throw an exception. Don't fall back to the old-style API way of returning false because an exceptional problem should not be silently ignored, and littering the code with if statements to ensure every method call succeeds does not make for readable code.
If the contract says "null is entirely possible", handle it with if statements.
Advertising
For getting a better grip on null problems, I would also urge you to get ReSharper for you and your team, but please note that this answer can be applied to any type of exception and error handling, the same principles applies.
With it comes attributes you can embed into your project(s) to flag these cases, and then ReSharper will highlight the code in question.
public void Write([NotNull] Stream stream)
[CanBeNull]
public SomeObject GetSomeObject()
To read more about the contract attributes that ReSharper uses, see
ReSharper NullReferenceException Analysis and Its Contracts
Contract Annotations in ReSharper 7
Well. Exceptions are just that. Exceptions. They are thrown when something unforseen has happened and should not be part of the normal program flow.
And that's what is happening here. You expected the argument to be specified when it's not. That is unexpected and you should therefore throw your own exception informing the user of that. If you want to get bonus points you can also include the reason to WHY the argument must be specified (if it's not obvious).
I've written a series of posts about exceptions: http://blog.gauffin.org/2013/04/what-is-exceptions/
From a performance standpoint it really depends what you're doing. The performance impact from a try/catch block when no exception is thrown is minimal (and if you really need that last few percent of performance, you probably should rewrite that part of your code in C++ anyway). Throwing exceptions does have a major impact on simpler operations such as string manipulation; but once you get file/database operations in the loop they're so much slower that again it becomes a trivial penalty. Throwing across an App Domain will have a non-trivial impact on just about anything though.
Performance in Operations/second:
Mode/operation Empty String File Database Complex
No exception 17,748,206 267,300 2,461 877 239
Catch without exception 15,415,757 261,456 2,476 871 236
Throw 103,456 68,952 2,236 864 236
Rethrow original 53,481 41,889 2,324 852 230
Throw across AppDomain 3,073 2,942 930 574 160
Additional test results along with the source for the tests is available from the article Performance implications of Exceptions in .NET
I would rather suggest you use if-statement for NullReference exception. For other exception, try-catch should be good enough.
The reason I suggest if-statement for NullReference exception is because C# will not tell which variable is null. if that line has more than one object could be null, you will loss track. If you are using if-statement, you can have better logging to help you get the enough information.
The main Question is if it is a good idea to have methods returning Null at all, personally i do not have any problem with this, but as soon as you try to access modifiers of an object returned from this method and you forget to check if it is assigned this becomes an issue.
Ken has a good answer about this:
If you are always expecting to find a value then throw the exception
if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the
application logic then return a null.
See this disscussion abou tthis issue:
Returning null is usually the best idea if you intend to indicate that
no data is available.
An empty object implies data has been returned, whereas returning null
clearly indicates that nothing has been returned.
Additionally, returning a null will result in a null exception if you
attempt to access members in the object, which can be useful for
highlighting buggy code - attempting to access a member of nothing
makes no sense. Accessing members of an empty object will not fail
meaning bugs can go undiscovered.
Some further reading:
No Null Beyond Method Scope
Should We Return Null From Our Methods?
using try catch for the statements is not an good idea. because when you use try catch them it seems that if some error comes the code will not turninate the application. but if you are sure about what kind of error can come you can tap the error at that point. that will not produce any unknown errors. for example.
string name = null;
here i am going to use the name variable and i am sure that this will throw Null Refrance Error .
try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error
}
catch(Exception ex)
{
// handle error to prevent application being crashed.
}
This is not a good practice while you can handle this kind of error and make your code more readable. like.
if(name !=null)
Console.writeLine("Name ={0}",name);
In my experience using if is better but only if you actually expect a null reference pointer. Without any bit of code or context its difficult to say when one option is better than the other.
There's also a matter of optimization - code in try-catch blocks won't be optimized.
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Also, catch blocks won't stop your code from halting when an error is hit.
Its always better to use Try Catch other than if else
Here Exceptions are two types namely handled and UN-handled exceptions
Even if u want to handle some function when the Exception u can handle it...
Handled exception always allows you to write some implementations inside the Catch block
Eg. An Alert Message, A new Function to handle when such exception occurs.
In this particular application, there is no separate data layer and the data access code is in the Entity itself. For example, consider a Customer entity, then in the Customer.cs file where the members and properties are defined, you have methods to load the Customer object as below
public bool TryLoad(int customerID, out Customer customer)
{
bool success = false
try
{
//code which calls the db and fills a SqlDataReader
ReadDataFromSqlDataReader(reader);
success = true;
}
catch(Exception ex)
{
LogError();
success = false;
}
return success;
}
Now, in the ReadDataFromSqlDataReader(reader), tryparse is used to load data from the reader into the object. e.g.
public void ReadDataFromSqlDataReader(reader)
{
int.TryParse(reader["CustomerID"].ToString(), out this.CustomerID);
PhoneNumber.TryParse(reader["PhoneNumber"].ToString(), out this.PhoneNumber);
... similar TryParse code for all the other fields..
}
Is using TryParse to read all the properties from the reader a good practise? A dev told me that its done this way as TryParse has a better performance than int.Parse. But wouldnt you want an exception to be throw when the value you are reading from the db does not conform to what your code expects? I mean in this case, if there is a wrong phone number in the db then perhaps the object shouldn't be initialized at all instead of loading an object with an empty phone number?
Yes, following the fail-fast principle, you would want an exception to be thrown the moment a value comes back that cannot be converted into the expected type.
If one of these operations fails and you continue as if nothing happened, you are likely to get weird errors that are hard to catch and hard to pinpoint: objects being added to the database when they should have been updating an existing row, data mysteriously disappearing, dogs and cats living together... you get the idea.
On the other hand, if you throw an exception immediately, you know exactly where your problem is and you can catch it and fix it before it becomes worse.
TryParse will work faster than Parse in case of failure simply because it doesn't have to throw an exception (which can be expensive), but if you're assuming that things will succeed (which this code is doing by not using the result of the parse), you should get equivalent performance using Parse.
What sort of validation are you doing when the data is being inserted and/or updated?
As long as you are applying some form of validation here, I personally would not be validating the data coming out of the Database as you should be confident that you are only putting in valid data.
Effective validation be performed when data is inserted into the database. It's not a good design with which bad data could be entered in the database. If database contains bad phone number, user should be asked to enter phone number again if its mandatory and if phone number is not that important, you could initialize phone number to null in case of bad data.
I wouldn't be using TryParse for that.
If my db had rubbish in it, I'd want that addressed.
If the data was ambiguous in terms of parsing (e.g. Varchar with int or double in it as a string)
I'd want to sort out my schema, TryParse as type detection would be a quick and simple hack.
If you would handle it, well yes you should throw an exception. But if you don't care about the exception and if you would filter the right data and use it (in this case non zeros) you can skip.
As, TryParse returns Boolean value. So, I can ByPass/Continue the Upcoming Logic/Any Database request on the basis of Boolean Value. I will not let the exception to occur in such scenaria. For that I will do the logging etc.
Parse
Throws an exception.
Use it if you are sure the value will be valid
TryParse
Returns a bool indicating whether it succeeded
It just try/catch internally that why is implemented without exceptions so that it is fast
Use it in case the value may be InValid
Most of my methods has check for null argument in the function so I thought instead of writing
Debug.Assert(x != null, "x should not be null");
if (x == null)
{
throw new ArgumentNullException("x");
}
everywhere, I would simply create a static class with static method to centralize it.
However that has its own issue which is if Debug.Assert gets triggered then VS will popup in the static method instead of where the calling method is going to be, which is where it like it to be.
Just curious if anyone has a better way to handle this scenario or just in general how to handle this repeated work?
Thanks!
Another approach are DataContracts from Microsoft Research.
There's very little point asserting x != null if you're going to explicitly throw an exception anyway. You'll see the exception in debug, unless you have some global exception handling - and even then you can break on all exceptions rather than just uncaught.
The time to use assert would be if you decided the safest release-mode code-path is to do something other than throw an exception, eg to return early from your function, initialise your variable to a default value, etc.
Not to dismiss the utilities mentioned in other answers, but you probably want to think carefully in a given case whether throwing an exception or asserting is appropriate (and this doesn't just apply to argument validation).
One approach puts everything in code except the name of the variable to minimize the amount of literal content in source:
Guard.Check(EGuards.NotNull, "x");
Another approach if you're into fluent extensions (i flip flop on liking this).
x.MustNotBeNull();
look at the Design By Contract for example in Sharp-architecture
You may also want to look at Enterprise Library Exception Hadling Block described here.
One of its features is centralized exception handling. If nothing else its open source so you could use it as a pattern for your own implementation.
I know that you should always check incoming params to a method for null. But what if I have this scenario with a try/catch referring to a local variable. Do I really need to check for null below? Because it's gonna catch it anyway if it's null and the next line of code tries to use the refundResponse variable:
public string DoRefund(...)
{
try
{
......
string refundTransactionID = string.Empty;
......
RefundTransactionResponseType refundResponse = transaction.DoRefund(...);
if (refundResponse != null)
refundTransactionID = refundResponse.RefundTransactionID;
.....
}
catch (Exception ex)
{
LogError(ex);
return ex.ToString();
}
}
Remember I'm talking specifically about local variables and checking those inside a method, not incoming params to a method.
All I'm asking here is do I need to check for null before setting refundTransactionID or do I just set it without the if assuming that the compiler will handle and throw if it is null which will be caught and thrown back as a string to the caller in this case.
or should it be
if (refundResponse == null)
return null;
or just take the check out completely for this local variable assignment and then since in this case I have a try/catch I'm handling any exceptions picked up by the compiler naturally by returning the exception as a string to the caller (it was not my decision to send back a string, it was a requirement by my boss...so bypass that debate for now):
refundTransactionID = refundResponse.RefundTransactionID;
ultimately the rest of the code further down the line in the method is dependent on a valid refundTransactionID.
Exceptions are for exceptional conditions. If you can check for a continuable error, do so, please!
I know that you should always check
incoming params to a method for null.
No, not necessarily. What you should specify is the contract of your method. It's perfectly acceptable (and common) to specify that you'll throw a NullPointer/NullReferenceException for a null parameter. Then you don't need any checking.
You can also check for null, but this only makes sense if you can actually handle a null usefully (e.g. substitute a default value).
You should have to check for null in that instance. Your application logic should be able to handle these kind of situations, without the need for exceptions.
An alternative to testing is the Null Object pattern. Instead of returning Null, or a valid transaction, the transaction::DoRefund() method returns a null object: an object that offers the same interface as the RefundTransactionResponseType instances, but its methods do nothing. With this there is no need to test whether for Null.
The should be used wisely as this can easily hide problems.
No you don't need to check for null, there. That opens up another question, though, do you really need to check for null in incoming parameters?
Remember: that's a behavior. You have to test that behavior.
But if you can't continue at that point let the exception propogate.
No, doesn't look like you should check for null here. And I also wouldn't check for null for ALL incoming parameters (as your description suggests).
It's also odd that you're returning a transactionID as a string OR the message of an exception. How will the caller of this method know if an exception happened?
If you really want to log the exception, how about something like this:
public string DoRefund(...)
{
try
{
return transaction.DoRefund(...).RefundTransactionID;
}
catch (Exception ex)
{
LogError(ex);
throw ex;
}
}
You should check for null rather than letting the exception handling handle it. As leppie said, exceptions are for exceptional conditions not normal flow of control. If you know what issues can occur then you should gracefully handle them.
Another thing to keep in mind is the performance impact of exceptions. When the exception is thrown the JVM has to unwind the call stack. In your example the exception is then also logged. All of this takes time and is much slower than a simple "if" check.
I'd suggest checking for the null then doing some kind of soft error handling instead of just letting it catch and throwing an error message.
It depends on what it means to your program when (refundResponse == null). If this has some meaning, then it makes sense to report a more informative error. If it should never happen and would indicate a flaw in the DoRefund method, then I think it's fine to allow the null to cause an exception later. In the latter case, I'd only have a specific check if you're suspicious of the method and whether it's behaving as it's supposed to.