Best practice for null testing [duplicate] - c#

To avoid all standard-answers I could have Googled on, I will provide an example you all can attack at will.
C# and Java (and too many others) have with plenty of types some of ‘overflow’ behaviour I don’t like at all (e.g type.MaxValue + type.SmallestValue == type.MinValue for example : int.MaxValue + 1 == int.MinValue).
But, seen my vicious nature, I’ll add some insult to this injury by expanding this behaviour to, let’s say an Overridden DateTime type. (I know DateTime is sealed in .NET, but for the sake of this example, I’m using a pseudo language that is exactly like C#, except for the fact that DateTime isn’t sealed).
The overridden Add method:
/// <summary>
/// Increments this date with a timespan, but loops when
/// the maximum value for datetime is exceeded.
/// </summary>
/// <param name="ts">The timespan to (try to) add</param>
/// <returns>The Date, incremented with the given timespan.
/// If DateTime.MaxValue is exceeded, the sum wil 'overflow' and
/// continue from DateTime.MinValue.
/// </returns>
public DateTime override Add(TimeSpan ts)
{
try
{
return base.Add(ts);
}
catch (ArgumentOutOfRangeException nb)
{
// calculate how much the MaxValue is exceeded
// regular program flow
TimeSpan saldo = ts - (base.MaxValue - this);
return DateTime.MinValue.Add(saldo)
}
catch(Exception anyOther)
{
// 'real' exception handling.
}
}
Of course an if could solve this just as easy, but the fact remains that I just fail to see why you couldn’t use exceptions (logically that is, I can see that when performance is an issue that in certain cases exceptions should be avoided).
I think in many cases they are more clear than if-structures and don’t break any contract the method is making.
IMHO the “Never use them for regular program flow” reaction everybody seems to have is not that well underbuild as the strength of that reaction can justify.
Or am I mistaken?
I've read other posts, dealing with all kind of special cases, but my point is there's nothing wrong with it if you are both:
Clear
Honour the contract of your method
Shoot me.

Have you ever tried to debug a program raising five exceptions per second in the normal course of operation ?
I have.
The program was quite complex (it was a distributed calculation server), and a slight modification at one side of the program could easily break something in a totally different place.
I wish I could just have launched the program and wait for exceptions to occur, but there were around 200 exceptions during the start-up in the normal course of operations
My point : if you use exceptions for normal situations, how do you locate unusual (ie exceptional) situations ?
Of course, there are other strong reasons not to use exceptions too much, especially performance-wise

Exceptions are basically non-local goto statements with all the consequences of the latter. Using exceptions for flow control violates a principle of least astonishment, make programs hard to read (remember that programs are written for programmers first).
Moreover, this is not what compiler vendors expect. They expect exceptions to be thrown rarely, and they usually let the throw code be quite inefficient. Throwing exceptions is one of the most expensive operations in .NET.
However, some languages (notably Python) use exceptions as flow-control constructs. For example, iterators raise a StopIteration exception if there are no further items. Even standard language constructs (such as for) rely on this.

My rule of thumb is:
If you can do anything to recover from an error, catch exceptions
If the error is a very common one (eg. user tried to log in with the wrong password), use returnvalues
If you can't do anything to recover from an error, leave it uncaught (Or catch it in your main-catcher to do some semi-graceful shutdown of the application)
The problem I see with exceptions is from a purely syntax point of view (I'm pretty sure the perfomance overhead is minimal). I don't like try-blocks all over the place.
Take this example:
try
{
DoSomeMethod(); //Can throw Exception1
DoSomeOtherMethod(); //Can throw Exception1 and Exception2
}
catch(Exception1)
{
//Okay something messed up, but is it SomeMethod or SomeOtherMethod?
}
.. Another example could be when you need to assign something to a handle using a factory, and that factory could throw an exception:
Class1 myInstance;
try
{
myInstance = Class1Factory.Build();
}
catch(SomeException)
{
// Couldn't instantiate class, do something else..
}
myInstance.BestMethodEver(); // Will throw a compile-time error, saying that myInstance is uninitalized, which it potentially is.. :(
Soo, personally, I think you should keep exceptions for rare error-conditions (out of memory etc.) and use returnvalues (valueclasses, structs or enums) to do your error checking instead.
Hope I understood your question correct :)

A first reaction to a lot of answers :
you're writing for the programmers and the principle of least astonishment
Of course! But an if just isnot more clear all the time.
It shouldn't be astonishing eg : divide (1/x) catch (divisionByZero) is more clear than any if to me (at Conrad and others) . The fact this kind of programming isn't expected is purely conventional, and indeed, still relevant. Maybe in my example an if would be clearer.
But DivisionByZero and FileNotFound for that matter are clearer than ifs.
Of course if it's less performant and needed a zillion time per sec, you should of course avoid it, but still i haven't read any good reason to avoid the overal design.
As far as the principle of least astonishment goes : there's a danger of circular reasoning here : suppose a whole community uses a bad design, this design will become expected! Therefore the principle cannot be a grail and should be concidered carefully.
exceptions for normal situations, how do you locate unusual (ie exceptional) situations ?
In many reactions sth. like this shines trough. Just catch them, no? Your method should be clear, well documented, and hounouring it's contract. I don't get that question I must admit.
Debugging on all exceptions : the same, that's just done sometimes because the design not to use exceptions is common. My question was : why is it common in the first place?

Before exceptions, in C, there were setjmp and longjmp that could be used to accomplish a similar unrolling of the stack frame.
Then the same construct was given a name: "Exception". And most of the answers rely on the meaning of this name to argue about its usage, claiming that exceptions are intended to be used in exceptional conditions. That was never the intent in the original longjmp. There were just situations where you needed to break control flow across many stack frames.
Exceptions are slightly more general in that you can use them within the same stack frame too. This raises analogies with goto that I believe are wrong. Gotos are a tightly coupled pair (and so are setjmp and longjmp). Exceptions follow a loosely coupled publish/subscribe that is much cleaner! Therefore using them within the same stack frame is hardly the same thing as using gotos.
The third source of confusion relates to whether they are checked or unchecked exceptions. Of course, unchecked exceptions seem particularly awful to use for control flow and perhaps a lot of other things.
Checked exceptions however are great for control flow, once you get over all the Victorian hangups and live a little.
My favorite usage is a sequence of throw new Success() in a long fragment of code that tries one thing after the other until it finds what it is looking for. Each thing -- each piece of logic -- may have arbritrary nesting so break's are out as also any kind of condition tests. The if-else pattern is brittle. If I edit out an else or mess up the syntax in some other way, then there is a hairy bug.
Using throw new Success() linearizes the code flow. I use locally defined Success classes -- checked of course -- so that if I forget to catch it the code won't compile. And I don't catch another method's Successes.
Sometimes my code checks for one thing after the other and only succeeds if everything is OK. In this case I have a similar linearization using throw new Failure().
Using a separate function messes with the natural level of compartmentalization. So the return solution is not optimal. I prefer to have a page or two of code in one place for cognitive reasons. I don't believe in ultra-finely divided code.
What JVMs or compilers do is less relevant to me unless there is a hotspot. I cannot believe there is any fundamental reason for compilers to not detect locally thrown and caught Exceptions and simply treat them as very efficient gotos at the machine code level.
As far as using them across functions for control flow -- i. e. for common cases rather than exceptional ones -- I cannot see how they would be less efficient than multiple break, condition tests, returns to wade through three stack frames as opposed to just restore the stack pointer.
I personally do not use the pattern across stack frames and I can see how it would require design sophistication to do so elegantly. But used sparingly it should be fine.
Lastly, regarding surprising virgin programmers, it is not a compelling reason. If you gently introduce them to the practice, they will learn to love it. I remember C++ used to surprise and scare the heck out of C programmers.

The standard anwser is that exceptions are not regular and should be used in exceptional cases.
One reason, which is important to me, is that when I read a try-catch control structure in a software I maintain or debug, I try to find out why the original coder used an exception handling instead of an if-else structure. And I expect to find a good answer.
Remember that you write code not only for the computer but also for other coders. There is a semantic associated to an exception handler that you cannot throw away just because the machine doesn't mind.

Josh Bloch deals with this topic extensively in Effective Java. His suggestions are illuminating and should apply to .NET as well (except for the details).
In particular, exceptions should be used for exceptional circumstances. The reasons for this are usability-related, mainly. For a given method to be maximally usable, its input and output conditions should be maximally constrained.
For example, the second method is easier to use than the first:
/**
* Adds two positive numbers.
*
* #param addend1 greater than zero
* #param addend2 greater than zero
* #throws AdditionException if addend1 or addend2 is less than or equal to zero
*/
int addPositiveNumbers(int addend1, int addend2) throws AdditionException{
if( addend1 <= 0 ){
throw new AdditionException("addend1 is <= 0");
}
else if( addend2 <= 0 ){
throw new AdditionException("addend2 is <= 0");
}
return addend1 + addend2;
}
/**
* Adds two positive numbers.
*
* #param addend1 greater than zero
* #param addend2 greater than zero
*/
public int addPositiveNumbers(int addend1, int addend2) {
if( addend1 <= 0 ){
throw new IllegalArgumentException("addend1 is <= 0");
}
else if( addend2 <= 0 ){
throw new IllegalArgumentException("addend2 is <= 0");
}
return addend1 + addend2;
}
In either case, you need to check to make sure that the caller is using your API appropriately. But in the second case, you require it (implicitly). The soft Exceptions will still be thrown if the user didn't read the javadoc, but:
You don't need to document it.
You don't need to test for it (depending upon how aggresive your
unit testing strategy is).
You don't require the caller to handle three use cases.
The ground-level point is that Exceptions should not be used as return codes, largely because you've complicated not only YOUR API, but the caller's API as well.
Doing the right thing comes at a cost, of course. The cost is that everyone needs to understand that they need to read and follow the documentation. Hopefully that is the case anyway.

How about performance? While load testing a .NET web app we topped out at 100 simulated users per web server until we fixed a commonly-occuring exception and that number increased to 500 users.

I think that you can use Exceptions for flow control. There is, however, a flipside of this technique. Creating Exceptions is a costly thing, because they have to create a stack trace. So if you want to use Exceptions more often than for just signalling an exceptional situation you have to make sure that building the stack traces doesn't negatively influence your performance.
The best way to cut down the cost of creating exceptions is to override the fillInStackTrace() method like this:
public Throwable fillInStackTrace() { return this; }
Such an exception will have no stacktraces filled in.

Here are best practices I described in my blog post:
Throw an exception to state an unexpected situation in your software.
Use return values for input validation.
If you know how to deal with exceptions a library throws, catch them at the lowest level possible.
If you have an unexpected exception, discard current operation completely. Don’t pretend you know how to deal with them.

I don't really see how you're controlling program flow in the code you cited. You'll never see another exception besides the ArgumentOutOfRange exception. (So your second catch clause will never be hit). All you're doing is using an extremely costly throw to mimic an if statement.
Also you aren't performing the more sinister of operations where you just throw an exception purely for it to be caught somewhere else to perform flow control. You're actually handling an exceptional case.

Apart from the reasons stated, one reason not to use exceptions for flow control is that it can greatly complicate the debugging process.
For example, when I'm trying to track down a bug in VS I'll typically turn on "break on all exceptions". If you're using exceptions for flow control then I'm going to be breaking in the debugger on a regular basis and will have to keep ignoring these non-exceptional exceptions until I get to the real problem. This is likely to drive someone mad!!

Lets assume you have a method that does some calculations. There are many input parameters it has to validate, then to return a number greater then 0.
Using return values to signal validation error, it's simple: if method returned a number lesser then 0, an error occured. How to tell then which parameter didn't validate?
I remember from my C days a lot of functions returned error codes like this:
-1 - x lesser then MinX
-2 - x greater then MaxX
-3 - y lesser then MinY
etc.
Is it really less readable then throwing and catching an exception?

Because the code is hard to read, you may have troubles debugging it, you will introduce new bugs when fixing bugs after a long time, it is more expensive in terms of resources and time, and it annoys you if you are debugging your code and the debugger halts on the occurence of every exception ;)

If you are using exception handlers for control flow, you are being too general and lazy. As someone else mentioned, you know something happened if you are handling processing in the handler, but what exactly? Essentially you are using the exception for an else statement, if you are using it for control flow.
If you don't know what possible state could occur, then you can use an exception handler for unexpected states, for example when you have to use a third-party library, or you have to catch everything in the UI to show a nice error message and log the exception.
However, if you do know what might go wrong, and you don't put an if statement or something to check for it, then you are just being lazy. Allowing the exception handler to be the catch-all for stuff you know could happen is lazy, and it will come back to haunt you later, because you will be trying to fix a situation in your exception handler based on a possibly false assumption.
If you put logic in your exception handler to determine what exactly happened, then you would be quite stupid for not putting that logic inside the try block.
Exception handlers are the last resort, for when you run out of ideas/ways to stop something from going wrong, or things are beyond your ability to control. Like, the server is down and times out and you can't prevent that exception from being thrown.
Finally, having all the checks done up front shows what you know or expect will occur and makes it explicit. Code should be clear in intent. What would you rather read?

You can use a hammer's claw to turn a screw, just like you can use exceptions for control flow. That doesn't mean it is the intended usage of the feature. The if statement expresses conditions, whose intended usage is controlling flow.
If you are using a feature in an unintended way while choosing to not use the feature designed for that purpose, there will be an associated cost. In this case, clarity and performance suffer for no real added value. What does using exceptions buy you over the widely-accepted if statement?
Said another way: just because you can doesn't mean you should.

As others have mentioned numerously, the principle of least astonishment will forbid that you use exceptions excessively for control flow only purposes. On the other hand, no rule is 100% correct, and there are always those cases where an exception is "just the right tool" - much like goto itself, by the way, which ships in the form of break and continue in languages like Java, which are often the perfect way to jump out of heavily nested loops, which aren't always avoidable.
The following blog post explains a rather complex but also rather interesting use-case for a non-local ControlFlowException:
http://blog.jooq.org/2013/04/28/rare-uses-of-a-controlflowexception
It explains how inside of jOOQ (a SQL abstraction library for Java), such exceptions are occasionally used to abort the SQL rendering process early when some "rare" condition is met.
Examples of such conditions are:
Too many bind values are encountered. Some databases do not support arbitrary numbers of bind values in their SQL statements (SQLite: 999, Ingres 10.1.0: 1024, Sybase ASE 15.5: 2000, SQL Server 2008: 2100). In those cases, jOOQ aborts the SQL rendering phase and re-renders the SQL statement with inlined bind values. Example:
// Pseudo-code attaching a "handler" that will
// abort query rendering once the maximum number
// of bind values was exceeded:
context.attachBindValueCounter();
String sql;
try {
// In most cases, this will succeed:
sql = query.render();
}
catch (ReRenderWithInlinedVariables e) {
sql = query.renderWithInlinedBindValues();
}
If we explicitly extracted the bind values from the query AST to count them every time, we'd waste valuable CPU cycles for those 99.9% of the queries that don't suffer from this problem.
Some logic is available only indirectly via an API that we want to execute only "partially". The UpdatableRecord.store() method generates an INSERT or UPDATE statement, depending on the Record's internal flags. From the "outside", we don't know what kind of logic is contained in store() (e.g. optimistic locking, event listener handling, etc.) so we don't want to repeat that logic when we store several records in a batch statement, where we'd like to have store() only generate the SQL statement, not actually execute it. Example:
// Pseudo-code attaching a "handler" that will
// prevent query execution and throw exceptions
// instead:
context.attachQueryCollector();
// Collect the SQL for every store operation
for (int i = 0; i < records.length; i++) {
try {
records[i].store();
}
// The attached handler will result in this
// exception being thrown rather than actually
// storing records to the database
catch (QueryCollectorException e) {
// The exception is thrown after the rendered
// SQL statement is available
queries.add(e.query());
}
}
If we had externalised the store() logic into "re-usable" API that can be customised to optionally not execute the SQL, we'd be looking into creating a rather hard to maintain, hardly re-usable API.
Conclusion
In essence, our usage of these non-local gotos is just along the lines of what [Mason Wheeler][5] said in his answer:
"I just encountered a situation that I cannot deal with properly at this point, because I don't have enough context to handle it, but the routine that called me (or something further up the call stack) ought to know how to handle it."
Both usages of ControlFlowExceptions were rather easy to implement compared to their alternatives, allowing us to reuse a wide range of logic without refactoring it out of the relevant internals.
But the feeling of this being a bit of a surprise to future maintainers remains. The code feels rather delicate and while it was the right choice in this case, we'd always prefer not to use exceptions for local control flow, where it is easy to avoid using ordinary branching through if - else.

Typically there is nothing wrong, per se, with handling an exception at a low level. An exception IS a valid message that provides a lot of detail for why an operation cannot be performed. And if you can handle it, you ought to.
In general if you know there is a high probability of failure that you can check for... you should do the check... i.e. if(obj != null) obj.method()
In your case, i'm not familiar enough with the C# library to know if date time has an easy way to check whether a timestamp is out of bounds. If it does, just call if(.isvalid(ts))
otherwise your code is basically fine.
So, basically it comes down to whichever way creates cleaner code... if the operation to guard against an expected exception is more complex than just handling the exception; than you have my permission to handle the exception instead of creating complex guards everywhere.

You might be interested in having a look at Common Lisp's condition system which is a sort of generalization of exceptions done right. Because you can unwind the stack or not in a controlled way, you get "restarts" as well, which are extremely handy.
This doesn't have anything much to do with best practices in other languages, but it shows you what can be done with some design thought in (roughly) the direction you are thinking of.
Of course there are still performance considerations if you're bouncing up and down the stack like a yo-yo, but it's a much more general idea than "oh crap, lets bail" kind of approach that most catch/throw exception systems embody.

I don't think there is anything wrong with using Exceptions for flow-control. Exceptions are somewhat similar to continuations and in statically typed languages, Exceptions are more powerful than continuations, so, if you need continuations but your language doesn't have them, you can use Exceptions to implement them.
Well, actually, if you need continuations and your language doesn't have them, you chose the wrong language and you should rather be using a different one. But sometimes you don't have a choice: client-side web programming is the prime example – there's just no way to get around JavaScript.
An example: Microsoft Volta is a project to allow writing web applications in straight-forward .NET, and let the framework take care of figuring out which bits need to run where. One consequence of this is that Volta needs to be able to compile CIL to JavaScript, so that you can run code on the client. However, there is a problem: .NET has multithreading, JavaScript doesn't. So, Volta implements continuations in JavaScript using JavaScript Exceptions, then implements .NET Threads using those continuations. That way, Volta applications that use threads can be compiled to run in an unmodified browser – no Silverlight needed.

But you won't always know what happens in the Method/s that you call. You won't know exactly where the exception was thrown. Without examining the exception object in greater detail....

I feel that there is nothing wrong with your example. On the contrary, it would be a sin to ignore the exception thrown by the called function.
In the JVM, throwing an exception is not that expensive, only creating the exception with new xyzException(...), because the latter involves a stack walk. So if you have some exceptions created in advance, you may throw them many times without costs. Of course, this way you can't pass data along with the exception, but I think that is a bad thing to do anyway.

There are a few general mechanisms via which a language could allow for a method to exit without returning a value and unwind to the next "catch" block:
Have the method examine the stack frame to determine the call site, and use the metadata for the call site to find either information about a try block within the calling method, or the location where the calling method stored the address of its caller; in the latter situation, examine metadata for the caller's caller to determine in the same fashion as the immediate caller, repeating until one finds a try block or the stack is empty. This approach adds very little overhead to the no-exception case (it does preclude some optimizations) but is expensive when an exception occurs.
Have the method return a "hidden" flag which distinguishes a normal return from an exception, and have the caller check that flag and branch to an "exception" routine if it's set. This routine adds 1-2 instructions to the no-exception case, but relatively little overhead when an exception occurs.
Have the caller place exception-handling information or code at a fixed address relative to the stacked return address. For example, with the ARM, instead of using the instruction "BL subroutine", one could use the sequence:
adr lr,next_instr
b subroutine
b handle_exception
next_instr:
To exit normally, the subroutine would simply do bx lr or pop {pc}; in case of an abnormal exit, the subroutine would either subtract 4 from LR before performing the return or use sub lr,#4,pc (depending upon the ARM variation, execution mode, etc.) This approach will malfunction very badly if the caller is not designed to accommodate it.
A language or framework which uses checked exceptions might benefit from having those handled with a mechanism like #2 or #3 above, while unchecked exceptions are handled using #1. Although the implementation of checked exceptions in Java is rather nuisancesome, they would not be a bad concept if there were a means by which a call site could say, essentially, "This method is declared as throwing XX, but I don't expect it ever to do so; if it does, rethrow as an "unchecked" exception. In a framework where checked exceptions were handled in such fashion, they could be an effective means of flow control for things like parsing methods which in some contexts may have a high likelihood of failure, but where failure should return fundamentally different information than success. I'm unaware of any frameworks that use such a pattern, however. Instead, the more common pattern is to use the first approach above (minimal cost for the no-exception case, but high cost when exceptions are thrown) for all exceptions.

One aesthetic reason:
A try always comes with a catch, whereas an if doesn't have to come with an else.
if (PerformCheckSucceeded())
DoSomething();
With try/catch, it becomes much more verbose.
try
{
PerformCheckSucceeded();
DoSomething();
}
catch
{
}
That's 6 lines of code too many.

Related

Appropriate usage of assertions and exceptions

I've read a bit around, trying to figure out when to use assertions and exceptions appropriately, but there's still something I'm missing to the big picture. Probably I just need more experience, so I'd like to bring some simple examples to better comprehend in what situations I should use use what.
Example 1: let us start with the classical situation of an invalid value. For example I have the following class, in which both fields must be positive:
class Rectangle{
private int height;
private int length;
public int Height{
get => height;
set{
//avoid to put negative heights
}
}
//same thing for length
}
Let me remark that I am not talking about how to deal with user input in this example, since I could just make a simple control flow for that. Though, I am facing with the idea that somewhere else there may be some unexpected error and I want this to be detected since I don't want an object with invald values. So I can:
Use Debug.Assert and just stop the program if that happens, so that I can correct possible errors when they come.
Throw an ArgumentOutOfRangeException to basically do the same thing? This feels wrong, so I should use that only if I know I'm going to handle it somewhere. Though, if I know where to handle the exception, shouldn't I fix the problem where it lies? Or maybe it is meant for things that may happen but you cannot control directly in your code, like an user input (well that can be dealt with, without an exception, but maybe something else can't) or loading data?
Question: did I get the meaning of assertions and exceptions right? Also, could you please give an example in which handling exceptions can be useful (because something you cannot control before happens)? I cannot figure out what else, beyond the cases I mentioned, can happen, but I clearly still lack experience here.
To expand a bit my question: I can think of a variety of reasons why an exception can be thrown, like a NullReferenceException, an IndexOutOfBoundsException, the IO exceptions like DirectoryNotFoundException or FileNotFoundException, etc. Though, I cannot figure out situations in which handling them becomes useful, apart from simply stopping the program (in which case, shouldn't an assertion be used?) or giving a simple message of where the problem has occured. I know even this is useful and exceptions are also meant to categorize "errors" and give clue to how to fix them. Though, is a simple message really all they are useful to? That's sounds fishy, so I'll stick with the "I've never faced a proper situation, 'cause of experience" mantra.
Example 2: let us now talk about the user input, using the first example. As I've anticipated, I won't use an exception just to check that the values are positive, as that's a simple control flow. But what happens if the user inputs a letter? Should I handle an exception here (maybe a simple ArgumentException) and give a message in the catch block? Or it can be avoided, too, through control flow (check if input is of type int, or something like that)?
Thanks to anyone who will clear my lingering doubts.
Throw an ArgumentOutOfRangeException to basically do the same thing? This feels wrong, so I should use that only if I know I'm going to handle it somewhere. Though, if I know where to handle the exception, shouldn't I fix the problem where it lies?
Your reasoning is pretty good here, but not quite right. The reason you're struggling is because exceptions are used for four things in C#:
boneheaded exceptions. A boneheaded exception is something like "invalid argument" when the caller could have known that the argument is invalid. If a boneheaded exception is thrown then the caller has a bug that should be fixed. You never have a catch(InvalidArgumentException) outside of a test case because it should never be thrown in production. These exceptions exist to help your callers write correct code by telling them very loudly when they've made a mistake.
vexing exceptions are boneheaded exceptions where the caller cannot know that the argument is invalid. These are design flaws in APIs and should be eliminated. They require you to wrap API calls with try-catches to catch what looks like an exception that should be avoided, not caught. If you find that you're writing APIs that require the caller to wrap calls in a try-catch, you're doing something wrong.
fatal exceptions are exceptions like thread aborted, out of memory, and so on. Something terrible has happened and the process cannot continue. There is very little point in catching these because there's not much you can do to improve the situation, and you might make it worse.
exogenous exceptions are things like "the network cable is unplugged". You expected the network cable to be plugged in; it is not, and there is no way you could have checked earlier to see if it was, because the time of checking and the time of using are different times; the cable could be unplugged between those two times. You have to catch these.
Now that you know what the four kinds of exceptions are, you can see what the difference is between an exception and an assertion.
An assertion is something that must logically be true always, and if it is not, then you have a bug that should be fixed. You never assert that the network cable is plugged in. You never assert that a caller-supplied value is not null. There should never be a test case that causes an assertion to fire; if there is, then the test case has discovered a bug.
You assert that after your in-place sort algorithm runs, the smallest element in a non-empty array is at the beginning. There should be no way that can be false, and if there is, you have a bug. So assert that fact.
A throw by contrast is a statement, and every statement should have a test case which exercises it. "This API throws when passed null by a buggy caller" is part of its contract, and that contract should be testable. If you find you're writing throw statements that have no possible test case that verifies that they throw, consider changing it to an assertion.
And finally, never pass invalid arguments and then catch a boneheaded exception. If you're dealing with user input, then the UI layer should be verifying that the input is syntactically valid, ie, numbers where numbers are expected. The UI layer should not be passing possibly-unvetted user code to a deeper API and then handling the resulting exception.
I see it that way. Assertions are for programmers. Exceptions are for users. You can have places in your code that you expect specific value. Then you can put assertion, for example:
public int Age
{
get { return age; }
set
{
age = value;
Debug.Assert(age == value);
}
}
This is just example. So if age != value there is no exception. But "hey programmer, something strange may have happened, look at this part of code".
You use exception when application don't know how to react in a specific situation. For example:
public int Divide(int a, int b)
{
Debug.Assert(b != 0); //this is for you as a programmer, but if something bad happened, user won't see this assert, but application also doesn't know what to do in situation like this, so you will add:
if(b == 0)
throw SomeException();
}
And SomeException might be handled somewhere else in your application.

When should I use a ThrowHelper method instead of throwing directly?

When is it appropriate to use a ThrowHelper method instead of throwing directly?
void MyMethod() {
...
//throw new ArgumentNullException("paramName");
ThrowArgumentNullException("paramName");
...
}
void ThrowArgumentNullException(string paramName) {
throw new ArgumentNullException(paramName);
}
I've read that calling a ThrowHelper method (a method with the only purpouse of throwing an exception) instead of throwing directly should yield smaller bytecode.
This, and the obvious encapsulation (another layer of indirection), may be good reasons to not throw directly, at least in some scenarios.
Anyway, IMO the drawbacks are not insubstantial too.
A part of the (exceptional) control flow is hidden
Exceptions end up having a more cryptic stacktrace
the compiler (2.0) will not recognize that ThrowHelper calls are exit points from a method, hence some code-around is necessary.
My limited experience is that often the overall design gets worse.
int MyMethod(int i) {
switch (i) {
case 1:
return 1;
default:
ThrowMyException();
}
return 0; // Unreachable (but needed) code
}
This may partly be a matter of personal taste. Anyway what are your personal guidelines about this issue? Do you find it is a good idea to use ThrowHelpers for all those common tasks like method param validation (ThrowArgumentNullException(paramName) and such)?
Am I missing something obvious on this issue?
Btw I'm trying not to mix this issue with the validation issue, e.g. a method like:
ThrowIfNameIsNullOrEmpty(name);
My default approach is to throw directly from the exceptional code branch.
The DRY principle and the rule of 3 guides when I would wrap that in a method: if I find myself writing the same 'throw' code 3 or more times, I consider wrapping it in a helper method.
However, instead of a method that throws, it's much better to write a Factory Method that creates the desired Exception and then throw it from the original place:
public void DoStuff(string stuff)
{
// Do something
throw this.CreateException("Boo hiss!");
}
private MyException CreateException(string message)
{
return new MyException(message);
}
This preserves the stack trace.
This seems like a needless abstraction to me. You have a method that does one thing, named as verbosely as the thing that it does.
The argument about less bytecode is practically meaningless since the size of your code rarely matters (you wouldn't be saving more than a kilobyte per instance of your program, unless you throw that exception from a ridiculous number of places in your source code). Meanwhile your stated drawbacks are all real concerns, especially where clarity of exception handling is concerned.
Basically abstracting away minor things like this usually comes back to bite you. (Some entertaining reading on the subject: http://www.joelonsoftware.com/articles/LeakyAbstractions.html)
I would say that the only reasonable time to do this is in something like the BCL where the amount of usage of the class is wide spread enough that the savings may be worth it. It would have to make sense, however. In your case, I don't think you're actually saving any space. Instances of ThrowHelper in the BCL reduce size by substituting enums for strings and method calls (to get string messages). Your case simply passes the same arguments and thus doesn't achieve any savings. It costs just as much to call your method as it does to throw the exception in place.
From what I've understood, the smaller bytecode is pretty much the only advantage (See this question), so I don't expect you'll see a lot of arguments for it in the answers here.
I always try to throw my own exceptions for the mere purpose of customization. I can throw a message that is going to tell me in short order what the problem is (and possibly where it originated from). As far as performance issues go, I try to limit the number of exceptions thrown on the release versions of my software as much as possible, so I have never actually thought about it too much. I am interested to see what other say though.
That is my 2 cents. Please take it as such.
There are two justifiable reasons to do this. The first is if the same exception message / info is supposed to be shared in multiple places.
The second is for performance reasons. Historically a throw in a method would prevent that method from being inlined which can drastically impact performance for small methods. You see this very often in collection types where small methods that modify the collection need to check the bounds before performing the modification.
The idea is that we want the normal case to be inlined as far up the stack as possible and to do so the throw has to stay in it's own method which is not inlined.
See these blog posts among many others for further explanation : https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#exceptions
https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/
One advantage not yet mentioned to using either a throw-helper or exception-factory method is the possibility of passing a delegate for such a purpose. When using a throw-helper delegate, one gains the possibility of not throwing (which would in some cases be a good thing; in other cases, a bad thing). For example:
string TryGetEntry(string key, Funct<problemCause, string> errorHandler)
{
if (disposed)
return errorHandler(problemCause.ObjectDisposed);
else if (...entry_doesnt_exist...)
return errorHandler(problemCause.ObjectNotFound);
else
return ...entry...;
}
string GetEntry(string key)
{
return TryGetEntry(key, ThrowExceptionOnError);
}
bool TryGetEntry(string key, ref result)
{
bool ok;
string result;
result = TryGetEntry(key, (problemCause theProblem) => {ok=false; return (string)null;});
return ok;
}
Using this approach, one may easily use one routine with a variety of error-handling strategies. One could eliminate the need for a closure by having the TryGetEntry method accept a generic type parameter along with a 'ref' parameter of that type and a delegate that accepts such a 'ref' parameter; the example is simpler, though, just using a closure.
Although having smaller bytecode seems only save you a few kb, it definetly "does" effect performance because more code have to be fetched/loaded to run your method which also means more cpu cache wasted. If you write high perf code where every micro-optimisation matters then it matters.
But what is more important you can localize or one day may want to localize your exception messages.

which is a better practice at exception handling?

if I have a specific exception that I expect when it is going to occur;
and to handle it for example I chose to display an error message upon its occurance, which would be better to do, and why?
Explanatory code:
try
{
string result = dictionary[key];
}
catch (KeyNotFoundException e)
{
//display error
}
or:
if(!dictionary.ContainsKey(key))
{
//display error
}
Generally, exceptions are used to indicate exceptional conditions - something that would not normally occur, but your program still needs to handle gracefully (eg a file being inaccessible or readonly, a network connection going down). Normal control flow, like checking for a value in a dictionary, should not use exceptions if there is an equivalent function that has the same effect without using exceptions.
Having extra try/catch statements in the code also makes it less readable, and having exception handlers around a block of code puts certain limitations on the CLR that can cause worse performance.
In your example, if it is expected that the dictionary will have a certain key value, I would do something like
string result;
if (!dictionary.TryGetValue(key, out result)
{
// display error
return; // or throw a specific exception if it really is a fatal error
}
// continue normal processing
This is a lot clearer than just having an exception handler round an element access
Neither.
The second option is better than the first. As you expect this to happen normally, it's better to avoid the exception. Exceptions should preferrably only be used for exceptional situations, i.e. something that you can't easily predict and test for.
The best option however is the TryGetValue method, as it does both check and fetch:
if (dictionary.TryGetValue(key, out result)) {
// use the result
} else {
// display error
}
The second approuch is better. Exception throwing can be very expensive.
The second approach is probably better. Remember that exceptions are used for exceptional circumstances. Use this principle to guide your decision:
If you require that the key exists in the dictionary as an application invariant, then assume that it is there and deal with the exception if it isn't there.
If your application code doesn't require that the entry exist in the dictionary, then call ContainsKey() first.
My guess is that the latter is probably the correct course of action.
Disclaimer: I generally eschew the advice that performance should be the primary consideration here. Only let performance impact your decision once you have proven that you have a bottleneck! Anything before that is premature optimization and will lead to unnecessarily complication application code.
The second approach is better for at least 3 reasons:
1) It is clearer. As a reader of your code, I expect an exception to indicate that something has gone wrong, even if it's handled.
2) When debugging with Visual Studio it's common to break on all exceptions, that makes it mildly annoying to deal with code which always throws an exception.
3) The second version is faster, but the effect is very small unless you are throwing many exceptions a second in a time-critical piece of code.
The second approach is better because throwing and hanlding exception has its performance hit. Throw rates above 100 per second are likely to noticeably impact the perfor-
mance of most applications. Consider Exceptions and Performance.
Exception handling is most useful when you need to provide an easy way out of a difficult situation - it can greatly simplify the code and decrease the potential for corner-case bugs.
It offers little advantage in very simple situations like this, and due to its performance penalty should not be used in such cases.
It all depends on what you're application is doing and what the specific code is doing.
As thecoop says exceptions should be used for exceptional conditions. As an illustration take writing to a file. If checking for the existence of the file would slow your application down and/or the absence of the file is a serious problem then allow the exception to occur and trap that. If it's not so critical or recreating the file isn't a problem then do the file existence check first.
I've seen it argued that all error handling should be done via exceptions (most recently in Clean Code by Robert Martin) but I don't agree.
It depends greatly on what the dictionary is meant to do. If there is a high chance that the key will not be found because of program design, then you should do the trygetvalue. However, if the design of your program is such that not finding the key is an exceptional event, you should use the exception handler method.
Just a reminder. It is not an exception.
An exception is something sounds like "no /etc on my UNIX machine".
If you get wrong sense, you'll write wrong code shown as above.

Best practices for exception management in Java or C# [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 7 years ago.
Improve this question
I'm stuck deciding how to handle exceptions in my application.
Much if my issues with exceptions comes from 1) accessing data via a remote service or 2) deserializing a JSON object. Unfortunately I can't guarantee success for either of these tasks (cut network connection, malformed JSON object that is out of my control).
As a result, if I do encounter an exception I simply catch it within the function and return FALSE to the caller. My logic is that all the caller really cares about is if the task was successful, not why it is wasn't successful.
Here's some sample code (in JAVA) of a typical method)
public boolean doSomething(Object p_somthingToDoOn)
{
boolean result = false;
try{
// if dirty object then clean
doactualStuffOnObject(p_jsonObject);
//assume success (no exception thrown)
result = true;
}
catch(Exception Ex)
{
//don't care about exceptions
Ex.printStackTrace();
}
return result;
}
I think this approach is fine, but I'm really curious to know what the best practices are for managing exceptions (should I really bubble an exception all the way up a call stack?).
In summary of key questions:
Is it okay to just catch exceptions but not bubble them up or formally notifying the system (either via a log or a notification to the user)?
What best practices are there for exceptions that don't result in everything requiring a try/catch block?
Follow Up/Edit
Thanks for all the feedback, found some excellent sources on exception management online:
Best Practices for Exception Handling | O'Reilly Media
Exception Handling Best Practices in .NET
Best Practices: Exception Management (Article now points to archive.org copy)
Exception-Handling Antipatterns
It seems that exception management is one of those things that vary based on context. But most importantly, one should be consistent in how they manage exceptions within a system.
Additionally watch out for code-rot via excessive try/catches or not giving a exception its respect (an exception is warning the system, what else needs to be warned?).
Also, this is a pretty choice comment from m3rLinEz.
I tend to agree with Anders Hejlsberg and you that the most callers only
care if operation is successful or not.
From this comment it brings up some questions to think about when dealing with exceptions:
What is the point this exception being thrown?
How does it make sense to handle it?
Does the caller really care about the exception or do they just care if the call was successful?
Is forcing a caller to manage a potential exception graceful?
Are you being respectful to the idoms of the language?
Do you really need to return a success flag like boolean? Returning boolean (or an int) is more of a C mindset than a Java (in Java you would just handle the exception) one.
Follow the error management constructs associated with the language :) !
It seems odd to me that you want to catch exceptions and turn them into error codes. Why do you think the caller would prefer error codes over exceptions when the latter is the default in both Java and C#?
As for your questions:
You should only catch exceptions that you can actually handle. Just
catching exceptions is not the right thing to do in most cases.
There are a few exceptions (e.g. logging and marshalling exceptions
between threads) but even for those cases you should generally
rethrow the exceptions.
You should definitely not have a lot of try/catch statements in your
code. Again, the idea is to only catch exceptions you can handle.
You may include a topmost exception handler to turn any unhandled
exceptions into something somewhat useful for the end user but
otherwise you should not try to catch each and every exception in
every possible place.
This depends on the application and the situation. If your building a library component, you should bubble up exceptions, although they should be wrapped to be contextual with your component. For example if your building an Xml Database and let's say you are using the file system to store your data, and you are using file system permissions to secure the data. You wouldn't want to bubble up a FileIOAccessDenied exception as that leaks your implementation. Instead you would wrap the exception and throw an AccessDenied error. This is especially true if you distribute the component to third parties.
As for if it's okay to swallow exceptions. That depends on your system. If your application can handle the failure cases and there is no benefit from notifying the user why it failed then go ahead, although I highly recommend that your log the failure. I've always found it frustating being called to help troubleshoot an issue and find they were swallowing the exception (or replacing it and throwing a new one instead without setting the inner exception).
In general I use the following rules:
In my components & libraries I only catch an exception if I intend to handle it or do something based on it. Or if I want to provide additional contextual information in an exception.
I use a general try catch at the application entry point, or the highest level possible. If an exception gets here I just log it and let it fail. Ideally exceptions should never get here.
I find the following code to be a smell:
try
{
//do something
}
catch(Exception)
{
throw;
}
Code like this serves no point and should not be included.
I would like to recommend another good source on the topic. It's an interview with inventors of C# and Java, Anders Hejlsberg and James Gosling respectively, on the topic of Java's Checked Exception.
Failure and Exceptions
There are also great resources at the bottom of the page.
I tend to agree with Anders Hejlsberg and you that the most callers only care if operation is successful or not.
Bill Venners: You mentioned
scalability and versioning concerns
with respect to checked exceptions.
Could you clarify what you mean by
those two issues?
Anders Hejlsberg: Let's start with
versioning, because the issues are
pretty easy to see there. Let's say I
create a method foo that declares it
throws exceptions A, B, and C. In
version two of foo, I want to add a
bunch of features, and now foo might
throw exception D. It is a breaking
change for me to add D to the throws
clause of that method, because
existing caller of that method will
almost certainly not handle that
exception.
Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, because any
implementation of it might have the
methods that you want to add in the
next version. So you've got to create
a new interface instead. Similarly
with exceptions, you would either have
to create a whole new method called
foo2 that throws more exceptions, or
you would have to catch exception D in
the new foo, and transform the D into
an A, B, or C.
Bill Venners: But aren't you breaking
their code in that case anyway, even
in a language without checked
exceptions? If the new version of foo
is going to throw a new exception that
clients should think about handling,
isn't their code broken just by the
fact that they didn't expect that
exception when they wrote the code?
Anders Hejlsberg: No, because in a lot
of cases, people don't care. They're
not going to handle any of these
exceptions. There's a bottom level
exception handler around their message
loop. That handler is just going to
bring up a dialog that says what went
wrong and continue. The programmers
protect their code by writing try
finally's everywhere, so they'll back
out correctly if an exception occurs,
but they're not actually interested in
handling the exceptions.
The throws clause, at least the way
it's implemented in Java, doesn't
necessarily force you to handle the
exceptions, but if you don't handle
them, it forces you to acknowledge
precisely which exceptions might pass
through. It requires you to either
catch declared exceptions or put them
in your own throws clause. To work
around this requirement, people do
ridiculous things. For example, they
decorate every method with, "throws
Exception." That just completely
defeats the feature, and you just made
the programmer write more gobbledy
gunk. That doesn't help anybody.
EDIT: Added more details on the converstaion
Checked exceptions are a controversial issue in general, and in Java in particular (later on I'll try to find some examples for those in favor and opposed to them).
As rules of thumb, exception handling should be something around these guidelines, in no particular order:
For the sake of maintainability, always log exceptions so that when you start seeing bugs, the log will assist in pointing you to the place your bug has likely started. Never leave printStackTrace() or the likes of it, chances are one of your users will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it.
Catch exceptions you can handle, and only those, and handle them, don't just throw them up the stack.
Always catch a specific exception class, and generally you should never catch type Exception, you are very likely to swallow otherwise important exceptions.
Never (ever) catch Errors!!, meaning: Never catch Throwables as Errors are subclasses of the latter. Errors are problems you will most likely never be able to handle (e.g. OutOfMemory, or other JVM issues)
Regarding your specific case, make sure that any client calling your method will receive the proper return value. If something fails, a boolean-returning method might return false, but make sure the places you call that method are able to handle that.
You should only catch the exceptions you can deal with. For example, if you're dealing with reading over a network and the connection times out and you get an exception you can try again. However if you're reading over a network and get a IndexOutOfBounds exception, you really can't handle that because you don't (well, in this case you wont) know what caused it. If you're going to return false or -1 or null, make sure it's for specific exceptions. I don't want a library I'm using returning a false on a network read when the exception thrown is the heap is out of memory.
Exceptions are errors that are not part of normal program execution. Depending on what your program does and its uses (i.e. a word processor vs. a heart monitor) you will want to do different things when you encounter an exception. I have worked with code that uses exceptions as part of normal execution and it is definitely a code smell.
Ex.
try
{
sendMessage();
if(message == success)
{
doStuff();
}
else if(message == failed)
{
throw;
}
}
catch(Exception)
{
logAndRecover();
}
This code makes me barf. IMO you should not recover from exceptions unless its a critical program. If your throwing exceptions then bad things are happening.
All of the above seems reasonable, and often your workplace may have a policy. At our place we have defined to types of Exception: SystemException (unchecked) and ApplicationException (checked).
We have agreed that SystemExceptions are unlikely to be recoverable and will bve handled once at the top. To provide further context, our SystemExceptions are exteneded to indicate where they occurred, e.g. RepositoryException, ServiceEception, etc.
ApplicationExceptions could have business meaning like InsufficientFundsException and should be handled by client code.
Witohut a concrete example, it's difficult to comment on your implementation, but I would never use return codes, they're a maintenance issue. You might swallow an Exception, but you need to decide why, and always log the event and stacktrace. Lastly, as your method has no other processing it's fairly redundant (except for encapsulation?), so doactualStuffOnObject(p_jsonObject); could return a boolean!
After some thought and looking at your code it seems to me that you are simply rethrowing the exception as a boolean. You could just let the method pass this exception through (you don't even have to catch it) and deal with it in the caller, since that's the place where it matters. If the exception will cause the caller to retry this function, the caller should be the one catching the exception.
It can at times happen that the exception you are encountering will not make sense to the caller (i.e. it's a network exception), in which case you should wrap it in a domain specific exception.
If on the other hand, the exception signals an unrecoverable error in your program (i.e. the eventual result of this exception will be program termination) I personally like to make that explicit by catching it and throwing a runtime exception.
If you are going to use the code pattern in your example, call it TryDoSomething, and catch only specific exceptions.
Also consider using an Exception Filter when logging exceptions for diagnostic purposes. VB has language support for Exception filters. The link to Greggm's blog has an implementation that can be used from C#. Exception filters have better properties for debuggability over catch and rethrow. Specifically you can log the problem in the filter and let the exception continue to propagate. That method allows an attaching a JIT (Just in Time) debugger to have the full original stack. A rethrow cuts the stack off at the point it was rethrown.
The cases where TryXXXX makes sense are when you are wrapping a third party function that throws in cases that are not truly exceptional, or are simple difficult to test without calling the function. An example would be something like:
// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse);
bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
try
{
parsedInt = ParseHexidecimal(numberToParse);
return true;
}
catch(NumberNotHexidecimalException ex)
{
parsedInt = 0;
return false;
}
catch(Exception ex)
{
// Implement the error policy for unexpected exceptions:
// log a callstack, assert if a debugger is attached etc.
LogRetailAssert(ex);
// rethrow the exception
// The downside is that a JIT debugger will have the next
// line as the place that threw the exception, rather than
// the original location further down the stack.
throw;
// A better practice is to use an exception filter here.
// see the link to Exception Filter Inject above
// http://code.msdn.microsoft.com/ExceptionFilterInjct
}
}
Whether you use a pattern like TryXXX or not is more of a style question. The question of catching all exceptions and swallowing them is not a style issue. Make sure unexpected exceptions are allowed to propagate!
I suggest taking your cues from the standard library for the language you're using. I can't speak for C#, but let's look at Java.
For example java.lang.reflect.Array has a static set method:
static void set(Object array, int index, Object value);
The C way would be
static int set(Object array, int index, Object value);
... with the return value being a success indicator. But you're not in C world any more.
Once you embrace exceptions, you should find that it makes your code simpler and clearer, by moving your error handling code away from your core logic. Aim to have lots of statements in a single try block.
As others have noted - you should be as specific as possible in the kind of exception you catch.
If you're going to catch an Exception and return false, it should be a very specific exception. You're not doing that, you're catching all of them and returning false. If I get a MyCarIsOnFireException I want to know about it right away! The rest of the Exceptions I might not care about. So you should have a stack of Exception handlers that say "whoa whoa something is wrong here" for some exceptions (rethrow, or catch and rethrow a new exception that explains better what happened) and just return false for others.
If this is a product that you'll be launching you should be logging those exceptions somewhere, it will help you tune things up in the future.
Edit: As to the question of wrapping everything in a try/catch, I think the answer is yes. Exceptions should be so rare in your code that the code in the catch block executes so rarely that it doesn't hit performance at all. An exception should be a state where your state machine broke and doesn't know what to do. At least rethrow an exception that explains what was happening at the time and has the caught exception inside of it. "Exception in method doSomeStuff()" isn't very helpful for anyone who has to figure out why it broke while you're on vacation (or at a new job).
My strategy:
If the original function returned void I change it to return bool. If exception/error occurred return false, if everything was fine return true.
If the function should return something then when exception/error occurred return null, otherwise the returnable item.
Instead of bool a string could be returned containing the description of the error.
In every case before returning anything log the error.
Some excellent answers here. I would like to add, that if you do end up with something like you posted, at least print more than the stack trace. Say what you were doing at the time, and Ex.getMessage(), to give the developer a fighting chance.
try/catch blocks form a second set of logic embedded over the first (main) set, as such they are a great way to pound out unreadable, hard to debug spaghetti code.
Still, used reasonably they work wonders in readability, but you should just follow two simple rules:
use them (sparingly) at the low-level to catch library handling issues, and stream them back into the main logical flow. Most of the error handling we want, should be coming from the code itself, as part of the data itself. Why make special conditions, if the returning data isn't special?
use one big handler at the higher-level to manage any or all of the weird conditions arising in the code that aren't caught at a low-level. Do something useful with the errors (logs, restarts, recoveries, etc).
Other than these two types of error handling, all of the rest of the code in the middle should be free and clear of try/catch code and error objects. That way, it works simply and as expected no matter where you use it, or what you do with it.
Paul.
I may be a little late with the answer but error handling is something that we can always change and evolve along time. If you want to read something more about this subject I wrote a post in my new blog about it. http://taoofdevelopment.wordpress.com
Happy coding.

Does This ASP.NET Consultant Know What He's Doing?

The IT department of a subsidiary of ours had a consulting company write them an ASP.NET application. Now it's having intermittent problems with mixing up who the current user is and has been known to show Joe some of Bob's data by mistake.
The consultants were brought back to troubleshoot and we were invited to listen in on their explanation. Two things stuck out.
First, the consultant lead provided this pseudo-code:
void MyFunction()
{
Session["UserID"] = SomeProprietarySessionManagementLookup();
Response.Redirect("SomeOtherPage.aspx");
}
He went on to say that the assignment of the session variable is asynchronous, which seemed untrue. Granted the call into the lookup function could do something asynchronously, but this seems unwise.
Given that alleged asynchronousness, his theory was that the session variable was not being assigned before the redirect's inevitable ThreadAbort exception was raised. This faulure then prevented SomeOtherPage from displaying the correct user's data.
Second, he gave an example of a coding best practice he recommends. Rather than writing:
int MyFunction(int x, int x)
{
try
{
return x / y;
}
catch(Exception ex)
{
// log it
throw;
}
}
the technique he recommended was:
int MyFunction(int x, int y, out bool isSuccessful)
{
isSuccessful = false;
if (y == 0)
return 0;
isSuccessful = true;
return x / y;
}
This will certainly work and could be better from a performance perspective in some situations.
However, from these and other discussion points it just seemed to us that this team was not well-versed technically.
Opinions?
Rule of thumb: If you need to ask if a consultant knows what he's doing, he probably doesn't ;)
And I tend to agree here. Obviously you haven't provided much, but they don't seem terribly competent.
I would agree. These guys seem quite incompetent.
(BTW, I'd check to see if in "SomeProprietarySessionManagementLookup," they're using static data. Saw this -- with behavior exactly as you describe on a project I inherited several months ago. It was a total head-slap moment when we finally saw it ... And wished we could get face to face with the guys who wrote it ... )
If the consultant has written an application that's supposed to be able to keep track of users and only show the correct data to the correct users and it doesn't do that, then clearly something's wrong. A good consultant would find the problem and fix it. A bad consultant would tell you that it was asynchronicity.
On the asynchronous part, the only way that could be true is if the assignment going on there is actually an indexer setter on Session that is hiding an asynchronous call with no callback indicating success/failure. This would seem to be a HORRIBLE design choice, and it looks like a core class in your framework, so I find it highly unlikely.
Usually asynchronous calls have a way to specify a callback so you can determine what the result is, or if the operation was successful. The documentation for Session should be pretty clear though on if it is actually hiding an asynchronous call, but yeah... doesn't look like the consultant knows what he is talking about...
The method call that is being assigned to the Session indexer cannot be asynch, because to get a value asynchronously, you HAVE to use a callback... no way around that, so if there is no explicit callback, it's definitely not asynch (well, internally there could be an asynchronous call, but the caller of the method would perceive it as synchronous, so it is irrelevant if the method internally for example invokes a web service asynchronously).
For the second point, I think this would be much better, and keep the same functionality essentially:
int MyFunction(int x, int y)
{
if (y == 0)
{
// log it
throw new DivideByZeroException("Divide by zero attempted!");
}
return x / y;
}
For the first point, that does indeed seem bizarre.
On the second one, it's reasonable to try to avoid division by 0 - it's entirely avoidable and that avoidance is simple. However, using an out parameter to indicate success is only reasonable in certain cases, such as int.TryParse and DateTime.TryParseExact - where the caller can't easily determine whether or not their arguments are reasonable. Even then, the return value is usually the success/failure and the out parameter is the result of the method.
Asp.net sessions, if you're using the built-in providers, won't accidentally give you someone else's session. SomeProprietarySessionManagementLookup() is the likely culprit and is returning bad values or just not working.
Session["UserID"] = SomeProprietarySessionManagementLookup();
First of all assigning the return value from an asynchronously SomeProprietarySessionManagementLookup() just wont work. The consultants code probably looks like:
public void SomeProprietarySessionManagementLookup()
{
// do some async lookup
Action<object> d = delegate(object val)
{
LookupSession(); // long running thing that looks up the user.
Session["UserID"] = 1234; // Setting session manually
};
d.BeginInvoke(null,null,null);
}
The consultant isn't totally full of BS, but they have written some buggy code. Response.Redirect() does throw a ThreadAbort, and if the proprietary method is asynchronous, asp.net doesn't know to wait for the asynchronous method to write back to the session before asp.net itself saves the session. This is probably why it sometimes works and sometimes doesn't.
Their code might work if the asp.net session is in-process, but a state server or db server wouldn't. It's timing dependent.
I tested the following. We use state server in development. This code works because the session is written to before the main thread finishes.
Action<object> d = delegate(object val)
{
System.Threading.Thread.Sleep(1000); // waits a little
Session["rubbish"] = DateTime.Now;
};
d.BeginInvoke(null, null, null);
System.Threading.Thread.Sleep(5000); // waits a lot
object stuff = Session["rubbish"];
if( stuff == null ) stuff = "not there";
divStuff.InnerHtml = Convert.ToString(stuff);
This next snippet of code doesn't work because the session was already saved back to state server by the time the asynchronous method gets around to setting a session value.
Action<object> d = delegate(object val)
{
System.Threading.Thread.Sleep(5000); // waits a lot
Session["rubbish"] = DateTime.Now;
};
d.BeginInvoke(null, null, null);
// wait removed - ends immediately.
object stuff = Session["rubbish"];
if( stuff == null ) stuff = "not there";
divStuff.InnerHtml = Convert.ToString(stuff);
The first step is for the consultant to make their code synchronous because their performance trick didn't work at all. If that fixes it, have the consultant properly implement using the Asynchronous Programming Design Pattern
I agree with him in part -- it's definitely better to check y for zero rather than catching the (expensive) exception. The out bool isSuccessful seems really dated to me, but whatever.
re: the asynchronous sessionid buffoonery -- may or may not be true, but it sounds like the consultant is blowing smoke for cover.
Cody's rule of thumb is dead right. If you have to ask, he probably doesn't.
It seems like point two its patently incorrect. .NET's standards explain that if a method fails it should throw an exception, which seems closer to the original; not the consulstant's suggestion. Assuming the exception is accurately & specifically describing the failure.
The consultants created the code in the first place right? And it doesn't work. I think you have quite a bit of dirt on them already.
The asynchronous answer sounds like BS, but there may be something in it. Presumably they have offered a suitable solution as well as pseudo-code describing the problem they themselves created. I would be more tempted to judge them on their solution rather than their expression of the problem. If their understanding is flawed their new solution won't work either. Then you'll know they are idiots. (In fact look round to see if you have a similar proof in any other areas of their code already)
The other one is a code style issue. There are a lot of different ways to cope with that. I personally don't like that style, but there will be circumstances under which it is suitable.
They're wrong on the async.
The assignment happens and then the page redirects. The function can start something asynchronously and return (and could even conceivably alter the Session in its own way), but whatever it does return has to be assigned in the code you gave before the redirect.
They're wrong on that defensive coding style in any low-level code and even in a higher-level function unless it's a specific business case that the 0 or NULL or empty string or whatever should be handled that way - in which case, it's always successful (that successful flag is a nasty code smell) and not an exception. Exceptions are for exceptions. You don't want to mask behaviors like this by coddling the callers of the functions. Catch things early and throw exceptions. I think Maguire covered this in Writing Solid Code or McConnell in Code Complete. Either way, it smells.
This guy does not know what he is doing. The obvious culprit is right here:
Session["UserID"] = SomeProprietarySessionManagementLookup();
I have to agree with John Rudy. My gut tells me the problem is in SomeProprietarySessionManagementLookup().
.. and your consultants do not sound to sure of themselves.
Storing in Session in not async. So that isn't true unless that function is async. But even so, since it isn't calling a BeginCall and have something to call on completion, the next line of code wouldn't execute until the Session line is complete.
For the second statement, while that could be used, it isn't exactly a best practice and you have a few things to note with it. You save the cost of throwing an exception, but wouldn't you want to know that you are trying to divide by zero instead of just moving past it?
I don't think that is a solid suggestion at all.
Quite strange. On the second item it may or may not be faster. It certainly isn't the same functionality though.
Typical "consultant" bollocks:
The problem is with whatever SomeProprietarySessionManagementLookup is doing
Exceptions are only expensive if they're thrown. Don't be afraid of try..catch, but throws should only occur in exceptional circumstances. If variable y shouldn't be zero then an ArgumentOutOfRangeException would be appropriate.
I'm guessing your consultant is suggesting use a status variable instead of exception for error handling is a better practice? I don't agree. How often does people forgot or too lazy to do error checking for return values? Also, pass/fail variable is not informative. There are more things can go wrong other than divide by zero like integer x/y is too big or x is NaN. When things go wrong, status variable cannot tell you what went wrong, but exception can. Exception is for exceptional case, and divide by zero or NaN are definitely exceptional cases.
The session thing is possible. It's a bug, beyond doubt, but it could be that the write arrives at whatever custom session state provider you're using after the next read. The session state provider API accommodates locking to prevent this sort of thing, but if the implementor has just ignored all that, your consultant could be telling the truth.
The second issue is also kinda valid. It's not quite idiomatic - it's a slightly reversed version of things like int.TryParse, which are there to avoid performance issues caused by throwing lots of exceptions. But unless you're calling that code an awful lot, it's unlikely it'll make a noticeable difference (compared to say, one less database query per page etc). It's certainly not something you should do by default.
If SomeProprietarySessionManagementLookup(); is doing an asynchronous assignment it would more likely look like this:
SomeProprietarySessionManagementLookup(Session["UserID"]);
The very fact that the code is assigning the result to Session["UserID"] would suggest that it is not supposed to be asynchronous and the result should be obtained before Response.Redirect is called. If SomeProprietarySessionManagementLookup is returning before its result is calculated they have a design flaw anyway.
The throw an exception or use an out parameter is a matter of opinion and circumstance and in actual practice won't amount to a hill of beans which ever way you do it. For the performance hit of exceptions to become an issue you would need to be calling the function a huge number of times which would probably be a problem in itself.
If the consultants deployed their ASP.NET application on your server(s), then they may have deployed it in uncompiled form, which means there would be a bunch of *.cs files floating around that you could look at.
If all you can find is compiled .NET assemblies (DLLs and EXEs) of theirs, then you should still be able to decompile them into somewhat readable source code. I'll bet if you look through the code you'll find them using static variables in their proprietary lookup code. You'd then have something very concrete to show your bosses.
This entire answer stream is full of typical programmer attitudes. It reminds me of Joel's 'Things you should never do' article (rewrite from scratch.) We don't really know anything about the system, other than there's a bug, and some guy posted some code online. There are so many unknowns that it is ridiculous to say "This guy does not know what he is doing."
Rather than pile on the Consultant, you could just as easily pile on the person who procured their services. No consultant is perfect, nor is a hiring manager ... but at the end of the day the real direction you should be taking is very clear: instead of trying to find fault you should expend energy into working collaboratively to find solutions. No matter how skilled someone is at their roles and responsibilities they will certainly have deficiencies. If you determine there is a pattern of incompentencies then you may choose to transition to another resource going forward, but assigning blame has never solved a single problem in history.
On the second point, I would not use exceptions here. Exceptions are reserved for exceptional cases.
However, division of anything by zero certainly does not equal zero (in math, at least), so this would be case specific.

Categories

Resources