This might be a bit of a stupid question but it has been bugging me so here goes
I know that the normal advice is that Exceptions are only meant to be used in exceptional circumstances but I also read people advocating to use exceptions when a method fails to fulfil its contract
Cancellation seems to me sit in a bit of a grey area between these two cases
Without exceptions if your class has a lot of cancelable actions your code ends up back checking error codes all over the place
Can cancelling be considered exceptional in this context?
Exceptions are most efficient for rare conditions that need non-local handling. It sounds like that applies here. So it is purely a stylistic question. Non-local control transfer can be more difficult to think about, but it will probably also mean shorter code. I would base the decision based on what language this is and how much of the existing code is already designed with exceptions. If you have exception-safe cleanup code already, go ahead and use them.
I wouldn't use an "exception" in its literal definition. What you could opt for is capturing the cancellation as a user driven value, a Boolean perhaps, that indicates that a user canceled out of an action, and use this Boolean to not perform the exhaustive error condition checks.
it depends on the language you are using.
in php for example its a common practice to throw an exception and catch it to interrupt for example a loop or recursion that is called within an object where its not sufficient to just jump up to the parent function.
consider this example:
<?php
class hideAndSeekWithOnlyOneOtherPlayer {
public function seek() {
foreach($rooms as $room) {
if($this->checkRoom($room)) {
$this->shoutThatIFoundYou();
return;
}
}
$this->shoutThatICantFindYou();
}
function checkRoom($room) {
$hideouts = $this->getPossibleHideoutsForRoom($room);
return $this->checkHideouts($hideouts);
}
function checkHideouts($hideouts) {
foreach($hideouts as $hideout) {
return $this->checkHideout($hideout);
}
return false;
}
function checkHideout($hideout) {
$this->walkToHideout();
return $this->seeIfPersonIsInsideHideout();
}
}
?>
its annoying to always pass the boolean value from one function to another, instead you could just throw an excemption in seeIfPersonIsInsideHideout() and dont care for the return values at all!
maby this is a bad example because it really gets important when you have multiple cases that can occour. then you have to bass back a constant or string or integer that you check for in an case statement etc.
its much better (easier to code and undestand, less error potential) to define your own exception class then!
Related
I have a situation where I need to perform dependent asynchronous operations. For example, check the database for data, if there is data, perform a database write (insert/update), if not continue without doing anything. I have written myself a promise based database API using promise-as3. Any database operation returns a promise that is resolved with the data of a read query, or with the Result object(s) of a write query. I do the following to nest promises and create one point of resolution or rejection for the entire 'initialize' operation.
public function initializeTable():Promise
{
var dfd:Deferred = new Deferred();
select("SELECT * FROM table").then(tableDefaults).then(resolveDeferred(dfd)).otherwise(errorHandler(dfd));
return dfd.promise;
}
public function tableDefaults(data:Array):Promise
{
if(!data || !data.length)
{
//defaultParams is an Object of table default fields/values.
return insert("table", defaultParams);
} else
{
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
}
}
public function resolveDeferred(deferred:Deferred):Function
{
return function resolver(value:*=null):void
{
deferred.resolve(value);
}
}
public function rejectDeferred(deferred:Deferred):Function
{
return function rejector(reason:*=null):void
{
deferred.reject(reason);
}
}
My main questions:
Are there any performance issues that will arise from this? Memory leaks etc.? I've read that function variables perform poorly, but I don't see another way to nest operations so logically.
Would it be better to have say a global resolved instance that is created and resolved only once, but returned whenever we need an 'empty' promise?
EDIT:
I'm removing question 3 (Is there a better way to do this??), as it seems to be leading to opinions on the nature of promises in asynchronous programming. I meant better in the scope of promises, not asynchronicity in general. Assume you have to use this promise based API for the sake of the question.
I usually don't write those kind of opinion based answers, but here it's pretty important. Promises in AS3 = THE ROOTS OF ALL EVIL :) And I'll explain you why..
First, as BotMaster said - it's weakly typed. What this means is that you don't use AS3 properly. And the only reason this is possible is because of backwards compatibility. The true here is, that Adobe have spent thousands of times so that they can turn AS3 into strongly type OOP language. Don't stray away from that.
The second point is that Promises, at first place, are created so that poor developers can actually start doing some job in JavaScript. This is not a new design pattern or something. Actually, it has no real benefits if you know how to structure your code properly. The thing that Promises help the most, is avoiding the so called Wall of Hell. But there are other ways to fix this in a natural manner (the very very basic thing is not to write functions within functions, but on the same level, and simply check the passed result).
The most important here is the nature of Promises. Very few people know what they actually do behind the scenes. Because of the nature of JavaScript (and ECMA script at all), there is no real way to tell if a function completed properly or not. If you return false / null / undefined - they are all regular return values. The only way they could actually say "this operation failed" is by throwing an error. So every promisified method, can potentially throw an error. And each error must be handled, or otherwise your code can stop working properly. What this means, is that every single action inside Promise is within try-catch block! Every time you do absolutely basic stuff, you wrap it in try-catch. Even this block of yours:
else
{
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
}
In a "regular" way, you would simply use else { return null }. But now, you create tons of objects, resolvers, rejectors, and finally - you try-catch this block.
I cannot stress more on this, but I think you are getting the point. Try-catch is extremely slow! I understand that this is not a big problem in such a simple case like the one I just mentioned, but imagine you are doing it more and on more heavy methods. You are just doing extremely slow operations, for what? Because you can write lame code and just enjoy it..
The last thing to say - there are plenty of ways to use asynchronous operations and make them work one after another. Just by googling as3 function queue I found a few. Not to say that the event-based system is so flexible, and there are even alternatives to it (using callbacks). You've got it all in your hands, and you turn to something that is created because lacking proper ways to do it otherwise.
So my sincere advise as a person worked with Flash for a decade, doing casino games in big teams, would be - don't ever try using promises in AS3. Good luck!
var dfd:Deferred = new Deferred();
select("SELECT * FROM table").then(tableDefaults).then(resolveDeferred(dfd)).otherwise(errorHandler(dfd));
return dfd.promise;
This is the The Forgotten Promise antipattern. It can instead be written as:
return select("SELECT * FROM table").then(tableDefaults);
This removes the need for the resolveDeferred and rejectDeferred functions.
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
I would either extract this to another function, or use Promise.when(null). A global instance wouldn't work because it would mean than the result handlers from one call can be called for a different one.
Most of you have probably bumped into a situation, where multiple things must be in check and in certain order before the application can proceed, for example in a very simple case of creating a listening socket (socket, bind, listen, accept etc.). There are at least two obvious ways (don't take this 100% verbatim):
if (1st_ok)
{
if (2nd_ok)
{
...
or
if (!1st_ok)
{
return;
}
if (!2nd_ok)
{
return;
}
...
Have you ever though of anything smarter, do you prefer one over the other of the above, or do you (if the language provides for it) use exceptions?
I prefer the second technique. The main problem with the first one is that it increases the nesting depth of the code, which is a significant issue when you've got a substantial number of preconditions/resource-allocs to check since the business part of the function ends up deeply buried behind a wall of conditions (and frequently loops too). In the second case, you can simplify the conceptual logic to "we've got here and everything's OK", which is much easier to work with. Keeping the normal case as straight-line as possible is just easier to grok, especially when doing maintenance coding.
It depends on the language - e.g. in C++ you might well use exceptions, while in C you might use one of several strategies:
if/else blocks
goto (one of the few cases where a single goto label for "exception" handling might be justified
use break within a do { ... } while (0) loop
Personally I don't like multiple return statements in a function - I prefer to have a common clean up block at the end of the function followed by a single return statement.
This tends to be a matter of style. Some people only like returning at the end of a procedure, others prefer to do it wherever needed.
I'm a fan of the second method, as it allows for clean and concise code as well as ease of adding documentation on what it's doing.
// Checking for llama integration
if (!1st_ok)
{
return;
}
// Llama found, loading spitting capacity
if (!2nd_ok)
{
return;
}
// Etc.
I prefer the second version.
In the normal case, all code between the checks executes sequentially, so I like to see them at the same level. Normally none of the if branches are executed, so I want them to be as unobtrusive as possible.
I use 2nd because I think It reads better and easier to follow the logic. Also they say exceptions should not be used for flow control, but for the exceptional and unexpected cases. Id like to see what pros say about this.
What about
if (1st_ok && 2nd_ok) { }
or if some work must be done, like in your example with sockets
if (1st_ok() && 2nd_ok()) { }
I avoid the first solution because of nesting.
I avoid the second solution because of corporate coding rules which forbid multiple return in a function body.
Of course coding rules also forbid goto.
My workaround is to use a local variable:
bool isFailed = false; // or whatever is available for bool/true/false
if (!check1) {
log_error();
try_recovery_action();
isFailed = true;
}
if (!isfailed) {
if (!check2) {
log_error();
try_recovery_action();
isFailed = true;
}
}
...
This is not as beautiful as I would like but it is the best I've found to conform to my constraints and to write a readable code.
For what it is worth, here are some of my thoughts and experiences on this question.
Personally, I tend to prefer the second case you outlined. I find it easier to follow (and debug) the code. That is, as the code progresses, it becomes "more correct". In my own experience, this has seemed to be the preferred method.
I don't know how common it is in the field, but I've also seen condition testing written as ...
error = foo1 ();
if ((error == OK) && test1)) {
error = foo2 ();
}
if ((error == OK) && (test2)) {
error = foo3 ();
}
...
return (error);
Although readable (always a plus in my books) and avoiding deep nesting, it always struck me as using a lot of unnecessary testing to achieve those ends.
The first method, I see used less frequently than the second. Of those times, the vast majority of the time was because there was no nice way around it. For the remaining few instances, it was justified on the basis of extracting a little more performance on the success case. The argument was that the processor would predict a forward branch as not taken (corresponding to the else clause). This depended upon several factors including, the architecture, compiler, language, need, .... Obviously most projects (and most aspects of the project) did not meet those requirements.
Hope this helps.
Is it legitimate to have exception handling code in a class constructor, or should it be avoided? Should one avoid having exception-generating code in a constructor?
Yes, it's perfectly reasonable. How else would you have a circumstance like this:
class List {
public List(int length) {
if(length < 0) {
throw new ArgumentOutOfRangeException(
"length",
"length can not be negative"
);
}
// okay, go!
}
}
A List with negative length is most certainly exceptional. You can not let this get back to the caller and have them think that construction was successful. What's the alternative, a CheckIfConstructionSucceeded instance member function? Yucky.
Or what about
class FileParser {
public FileParser(string path) {
if(!File.Exists(path)) {
throw new FileNotFoundException(path);
}
// okay, go!
}
}
Again, this is a throw and nothing else is acceptable.
Assuming it's C++ you're talking about, raising exceptions is actually the only way to signal errors in a constructor - so this definitely shouldn't be avoided (*)
As to handling exceptions inside constructors, this is also perfectly valid, granted that you actually can handle the exception. Just follow the common rule here: catch exceptions at the level where you can handle them / do something meaningful about them.
(*) As long as you're not of the cult
that avoids exceptions in C++
In C++, ctors are best placed to throw exceptions back up. FAQ:17.2
I believe it's valid to throw an exception in a constructor to stop the creation of the object.
In general, I think that exception-generating code should be avoided whenever possible in constructors. This is very language specific, however - in some languages, constructors throwing an exception cause unrecoverable issues, but in some other languages, it's fine.
Personally, I try to make my constructors do as little as possible to put the object into a valid state. This would, in general, mean that they are not going to throw, unless it's a truly exception case (which I can't really handle anyways).
Anywhere there is the possibility of an exception being thrown, the "best practice" is to handle it, constructor or otherwise.
It does add another layer of complexity to the constructor, since you have to ensure everything is initialized correctly even if an error does occur, but it's better than having buggy code :)
Sure, fail as early as you can! Inside constructors some validation of input params can go wrong, so it is defintely worth to fail, instead of proceeding with inconsistent built data.
Constructor(Param param){
if(param == null)
throw new IllegalArgumentException(...);
}
when writing small functions I often have the case that some parameters are given to a function which itself only passes them to different small functions to serve its purpose.
For example (C#-ish Syntax):
public void FunctionA(object param)
{
DoA(param);
DoB(param);
DoC(param);
// etc.
}
private void DoA(object param)
{
DoD(param);
}
private void DoD(object param)
{
// Error if param == null
param.DoX();
}
So the parameters are not used inside the called function but "somewhere" in the depths of the small functions that do the job.
So when is it best to check if my param-Object is null?
When checking in FunctionA:
Pro:
-There is no overhead through the use of further methods which at last will do nothing because object is null.
Con:
-My syntactically wonderful FunctionA is dirtied by ugly validation code.
When checking only when param-object is used:
Pro:
-My syntactically wonderful FunctionA keeps a joy to read :)
Cons:
-There will be overhead through calling methods which will do nothing because the param-object is null.
-Further cons I don't think about at the moment.
Always put it as far down the call stack as possible, so that if you later refactor the code and something else calls DoD other than DoA you have the check in place and don't have to rework your parameter checks. The overhead of a small null check and possibly a few extra method calls is going to be trivial in most cases and doing the check an extra few times is not something you should be worrying about.
Unless you think the value is likely to be null the vast majority of the time, I'd put the validation in DoD(). If you put it in FunctionA() you'll have to repeat the validation code later when you decide FunctionB() also needs to use DoD(). To me, the extra overhead is worth not having to repeat myself.
As a guideline, I make a habit of it to check every parameter that is used by the method, even including my own private variables. I would therefore only check for nil in your DoD method.
You might want to check out Bertrand Meyers Design By Contract mantra.
Fail early. Unless a partial result is preferable to no result at all, execution should stop as soon as the code can detect that there is a problem. Why should the code run through several methods when the result downstream is going to be an invalid or missing argument?
If it is possible that the downstream methods could be called separately then validation could be handled by a call to ca common validation methed as has already been suggested.
Always check everything :) Coming from the deep bowels of coding libraries for embedded systems, this is the method I'd use:
public void FunctionA(object param)
{
assert(param != null && param.canDoX());
DoA(param);
DoB(param);
DoC(param);
// etc.
}
private void DoA(object param)
{
assert(param != null && param.canDoX());
DoD(param);
}
private void DoD(object param)
{
assert(param != null && param.canDoX());
if ( param != null )
param.DoX();
else
// Signal error, for instance by throwing a runtime exception
// This error-handling is then verified by a unit test that
// uses a release build of the code.
}
To de-clutter this, the obvious solution is to break out the validation to a separate validator function. Using a C-style preprocessor, or just sticking to asserts, it should be trivial to have this "paranoid" validation excluded from release builds.
It's the caller's responsibility to pass a valid parameter. In this case:
if(param != null)
{
FunctionA(param);
}
I know two approaches to Exception handling, lets have a look at them.
Contract approach.
When a method does not do what it says it will do in the method header, it will throw an exception. Thus the method "promises" that it will do the operation, and if it fails for some reason, it will throw an exception.
Exceptional approach.
Only throw exceptions when something truly weird happens. You should not use exceptions when you can resolve the situation with normal control flow (If statements). You don't use Exceptions for control flow, as you might in the contract approach.
Lets use both approaches in different cases:
We have a Customer class that has a method called OrderProduct.
contract approach:
class Customer
{
public void OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
throw new NoCreditException("Not enough credit!");
// do stuff
}
}
exceptional approach:
class Customer
{
public bool OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
return false;
// do stuff
return true;
}
}
if !(customer.OrderProduct(product))
Console.WriteLine("Not enough credit!");
else
// go on with your life
Here I prefer the exceptional approach, as it is not truly Exceptional that a customer has no money assuming he did not win the lottery.
But here is a situation I err on the contract style.
Exceptional:
class CarController
{
// returns null if car creation failed.
public Car CreateCar(string model)
{
// something went wrong, wrong model
return null;
}
}
When I call a method called CreateCar, I damn wel expect a Car instance instead of some lousy null pointer, which can ravage my running code a dozen lines later. Thus I prefer contract to this one:
class CarController
{
public Car CreateCar(string model)
{
// something went wrong, wrong model
throw new CarModelNotKnownException("Model unkown");
return new Car();
}
}
Which do style do you use? What do you think is best general approach to Exceptions?
I favor what you call the "contract" approach. Returning nulls or other special values to indicate errors isn't necessary in a language that supports exceptions. I find it much easier to understand code when it doesn't have a bunch of "if (result == NULL)" or "if (result == -1)" clauses mixed in with what could be very simple, straightforward logic.
My usual approach is to use contract to handle any kind of error due to "client" invocation, that is, due to an external error (i.e ArgumentNullException).
Every error on the arguments is not handled. An exception is raised and the "client" is in charge of handling it. On the other hand, for internal errors always try to correct them (as if you can't get a database connection for some reason) and only if you can't handle it reraise the exception.
It's important to keep in mind that most unhandled exception at such level will not be able to be handled by the client anyway so they will just probably go up to the most general exception handler, so if such an exception occurs you are probably FUBAR anyway.
I believe that if you are building a class which will be used by an external program (or will be reused by other programs) then you should use the contract approach. A good example of this is an API of any kind.
If you are actually interested in exceptions and want to think about how to use them to construct robust systems, consider reading Making reliable distributed systems in the presence of software errors.
Both approaches are right. What that means is that a contract should be written in such a way as to specify for all cases that are not truly exceptional a behavior that does not require throwing an exception.
Note that some situations may or may not be exceptional based upon what the caller of the code is expecting. If the caller is expecting that a dictionary will contain a certain item, and absence of that item would indicate a severe problem, then failure to find the item is an exceptional condition and should cause an exception to be thrown. If, however, the caller doesn't really know if an item exists, and is equally prepared to handle its presence or its absence, then absence of the item would be an expected condition and should not cause an exception. The best way to handle such variations in caller expectation is to have a contract specify two methods: a DoSomething method and a TryDoSomething method, e.g.
TValue GetValue(TKey Key);
bool TryGetValue(TKey Key, ref TValue value);
Note that, while the standard 'try' pattern is as illustrated above, some alternatives may also be helpful if one is designing an interface which produces items:
// In case of failure, set ok false and return default<TValue>.
TValue TryGetResult(ref bool ok, TParam param);
// In case of failure, indicate particular problem in GetKeyErrorInfo
// and return default<TValue>.
TValue TryGetResult(ref GetKeyErrorInfo errorInfo, ref TParam param);
Note that using something like the normal TryGetResult pattern within an interface will make the interface invariant with respect to the result type; using one of the patterns above will allow the interface to be covariant with respect to the result type. Also, it will allow the result to be used in a 'var' declaration:
var myThingResult = myThing.TryGetSomeValue(ref ok, whatever);
if (ok) { do_whatever }
Not quite the standard approach, but in some cases the advantages may justify it.