views:

313

answers:

10

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.

+11  A: 

Exceptions are for exceptional conditions. If you can check for a continuable error, do so, please!

leppie
yes but the compiler is already going to throw a null exception if I try to use refundResponse if for some reason it's ever null. So why throw an exception in this case when the compiler will anyway and the compiler's exception message is good enough? That's what I'm debating...maybe I'm wrong but that's how it would go down if it was null and I did not have that check in there...the try/catch would pick it up.
CoffeeAddict
I"m simply checking for null before setting the transactionID. That's what I'm asking about specifically. Do I really need to do this for a local variable or do I let the compiler throw an exception naturally if when it hits the line that tries to set that transactionID.
CoffeeAddict
what is deemed an exceptional condition then, null?
CoffeeAddict
@coffeeaddict: Kinda, but depending on the caller, and your application type (eg library, web service, local class). If you think it is never going to be `null`, then a check is not worthy. OTOH, if you have unknown callers that could pass in null, you might want to indicate in a better way what is wrong. It is more of an opinion, than the 'law'. Also, null may have some other meaning, besides being an error.
leppie
+1  A: 

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.

A: 

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.

Jisaak
well in this case the error handling is done on the caller end..as this is a web service method that's to be consumed by my boss for his admin system and that's what I was told to do, return a string. Yea I think it's stupid.
CoffeeAddict
+1  A: 

But if you can't continue at that point let the exception propogate.

BrennaSoft
+7  A: 

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).

sleske
Nonetheless, it is conventional on .NET to throw `ArgumentNullException` when an argument that is not supposed to be `null` receives a `null` value.
Pavel Minaev
@sleske: It's usually better to throw an `ArgumentNullException` at the start of your method with information about the parameter that is null. If you just ignore the bad input and let your code throw a `NullReferenceException` at some point later, you might already have made several internal calls before that happens. By that time the exception might come from some undocumented internal function and the parameter name could be different there from the externally visible name and therefore not make immediate sense to the caller.
Mark Byers
Pavel, this is not an argument. It's a local variable inside a method.
CoffeeAddict
@Pavel, @Mark: Thanks for the info, good points. I come from Java, where throwing NPE is quite common. Jave does not have ArgumentNullException (just IllegalArgumentException). The distinction is interesting though.
sleske
@coffeeaddict, I was commenting on this specific answer (which talks about contracts and parameters), not on question.
Pavel Minaev
+2  A: 

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.

Colour Blend
well I'm handling it in this case upstream. Any exceptions that happen in that try, will be returned to the caller, in this case this is a web service method and my boss wanted for some reason to return just a string that said "success" or "fail" which to me is bad practice. It's like returning a true/false back which is just wrong when a transaction takes place.
CoffeeAddict
A: 

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;
        } 
    }
Shawn Miller
I believe this would clear this stack trace. But maybe doing aLogError(ex);throw;That would continue the exception up the stack.
galford13x
well my boss is the only caller and his requirements was for all these web service methods in my web service to return "success" or "fail". So in this case, he could check for "Approved" and if it's not approved thus he'll get an error message back.
CoffeeAddict
well I'm not throwing in my catch...yes you would be right but I'm returning the caught exception (if lets say that response variable was null) as a string back to the caller...again this was a requirement to return it as a string.
CoffeeAddict
+2  A: 

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.

philippe
ah, a friend of mine suggested this also. Nice. But what if your boss says no? you can't use that pattern. ;)
CoffeeAddict
Keep in mind this web service method is gonna be called from another language other than .NET also....not that it makes a difference in your response to my problem.
CoffeeAddict
+1  A: 

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.

brainimus
A: 

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.

Dan Bryant