SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 60
  1. #1
    SitePoint Addict n0other's Avatar
    Join Date
    Feb 2005
    Posts
    290
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The practical use of exceptions.

    Hi all. I'm having a hard time understanding the "real" or practical use of exceptions. Using it just because someone else does or because it makes the code prettier doesn't sound too reasonable to me.

    I've had a discussion with my colleague and his main point was "ability to classify errors", umm what's the use for that? And more importantly, what's the use of throwing blablablaExceptions when that exception is an empty class extending the base Exception? I've seen that done alot in advanced projects like php Doctrine etc.

    Thanks for any clarifications guys.

  2. #2
    SitePoint Evangelist praetor's Avatar
    Join Date
    Aug 2005
    Posts
    479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I use exceptions mainly for code elegance. It's much easier to work with
    Code PHP:
    try
    {
      //some code that may throw an exception
    }
     
    catch(ExceptionType1 $ex)
    {
     //handle exception
    }
     
    catch(ExceptionType2 $ex)
    {
     //handle exception
    }
     
    catch (Exception $ex)
    {
     //generic handler
    }
    rather than
    Code PHP:
    $rez= doStuff();
    if ($rez!=0)
    switch $rez
    {
     case 1: //error type1;
     case 2: //error type 2;
     // ..
    }

    With exceptions you can also see the whole calling stack.
    Is better not to use exception as a 'go to', only to properly handle some expected errors.
    A global exception handler is good too, because it catches the errors you've missed and you can log easily the details.

  3. #3
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Exceptions break the fundamental OOP principle of encapsulation: object A is able to send a message to object B without holding a reference to it. Normally you have to figure out how to design and build an object graph in order to get objects talking to each other. Exceptions create a kind of wormhole connecting two distant points, something outside the normal laws of physics.

    Exceptions don't just send messages: they also stop execution of code beyond the throw point. What this means is that a lower level object (the thrower) is taking a control flow decision which probably ought to be made by a higher level object. It should of course be able to identify its own error state but it shouldn't really know what this means to the wider app. The context ought to be defined by a higher level object. For example, suppose you wanted to use a domain object in a variety of situations; in some cases you want the "drop everything now" behaviour but not in others. If the object throws an exception you're stuffed.

    I haven't been coding in php5 for very long so maybe there's something I'm missing. It really doesn't look like good OOP design though, however convenient it might be. An emergency escape route might seem to make sense in "exceptional circumstances" but, again, where does the reponsibility to identify an exceptional circumstance lie?

  4. #4
    SitePoint Evangelist praetor's Avatar
    Join Date
    Aug 2005
    Posts
    479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well afaik, the bumble bee defies the laws of aerodynamics. Yet it flies.

    I guess the practical side of exception outweights their 'defiance' of good OOP.

  5. #5
    SitePoint Addict n0other's Avatar
    Join Date
    Feb 2005
    Posts
    290
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Praetor, I still can't see the practical use for them, as I said, I'm not going to use them because it makes my code look prettier..

    Off Topic:


    bumble bee defies the laws of aerodynamics only as they were known in the beginning of the flying era. Scientists used too simplified model of bumblee bee flight not weighting some important variables.

    Wikipedia:

    It is believed[citation needed] that the calculations which purported to show that bumblebees cannot fly are based upon a simplified linear treatment of oscillating aerofoils. The method assumes small amplitude oscillations without flow separation. This ignores the effect of dynamic stall, an airflow separation inducing a large vortex above the wing, which briefly produces several times the lift of the aerofoil in regular flight. More sophisticated aerodynamic analysis shows that the bumblebee can fly because its wings encounter dynamic stall in every oscillation cycle.

    It's just a myth, stop spreading it.
    Last edited by stymiee; Jun 10, 2007 at 16:04. Reason: fixed offtopic tags

  6. #6
    SitePoint Evangelist praetor's Avatar
    Join Date
    Aug 2005
    Posts
    479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For me exceptions are practical. I simply hate the 'switch' or 'if' spaghetti to check different values. They are practical because of their elegance. Of course, there is more to say about exceptions, but this is my main reason for using them.

    Off Topic:


    I was certain that someone would check the bumble bee thing
    Well all is true until the next study that will contradict it.

  7. #7
    Employed Again Viflux's Avatar
    Join Date
    May 2003
    Location
    London, On.
    Posts
    1,127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Somewhere in an obscure class buried deep in your code base, you have to open a file.

    What if that file doesn't exist?

    Where should you handle that error?

    If you handle it at the class level, then you're coupling your error handling to the class implementation. I prefer to throw an exception, and allow the calling application choose how to handle the error (recovery, stop processing, whatever you want). You could do this without exceptions, but then you'd have to return a status code along with each request. And then check that status code. And then react based on that status code, or pass that status code further up the hierarchy.

    To counter the point about exceptions breaking encapsulations, I don't see it as Object B sending a message to Object A. I see it as Object B sending a message. A isn't listening for messages from B, it is just listening to messages (or not). They do not know about each other, and they are not communicating in that sense. One is sending a message for *any* listener, and the other is listening for *any* message. That makes a world of difference to me.

  8. #8
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The throwing function isn't breaking any encapsulation. If the caller wants to catch the exception, it can. Otherwise, it will bubble up until someone catches it -- Ultimately at the top-level, generating an error.

    Exceptions provide a mechanism, which allows your code to return with an error, without forcing you to explicitly checking for it, each time you call a functions. Take a look at the old PEAR class library to get an idea of the kind of code, exceptions remedies; if (PEAR::isError($foo)) return $foo; all over the place isn't a pretty sight.

  9. #9
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Viflux View Post
    I don't see it as Object B sending a message to Object A. I see it as Object B sending a message. A isn't listening for messages from B, it is just listening to messages (or not). They do not know about each other, and they are not communicating in that sense. One is sending a message for *any* listener, and the other is listening for *any* message.
    Agreed the Observer behaviour is an important characteristic of exceptions but the thrower is doing more than just notifying any catcher-observers: it has also taken the decision to abort the current execution path.

    Well afaik, the bumble bee defies the laws of aerodynamics. Yet it flies.
    If the tests are passing with a stalling bumblebee, it must be good. Theory is important - figuring out which bits of logic belong where is what OOP design is all about - but it should have a practical payoff. I guess this would only matter if you wanted to use the (thrower) object in some other context, ie without the "drop everything now" behaviour.

  10. #10
    Put your best practices away. The New Guy's Avatar
    Join Date
    Sep 2002
    Location
    Canada
    Posts
    2,087
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by praetor View Post
    Off Topic:


    I was certain that someone would check the bumble bee thing
    Well all is true until the next study that will contradict it.
    Off Topic:


    "More sophisticated aerodynamic analysis shows that the bumblebee can fly because its wings encounter dynamic stall in every oscillation cycle." - Wikipedia
    "A nerd who gets contacts
    and a trendy hair cut is still a nerd"

    - Stephen Colbert on Apple Users

  11. #11
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    > it has also taken the decision to abort the current execution path.

    Well, that's the whole point of it, ain't it? That is why it's called an exception, because it's an exceptional circumstance. I don't agree with the point that the use of Exceptions break class encapsulation, however I can see how they could be abused.

    But that isn't a failing of Exceptions, but purely a bad developer who lacks the understanding.

  12. #12
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    Agreed the Observer behaviour is an important characteristic of exceptions but the thrower is doing more than just notifying any catcher-observers: it has also taken the decision to abort the current execution path.
    I wouldn't say it's made the 'decision' to abort the current execution path. Decisions usually imply that there's more than one option; I'd make the argument that exceptions make it possible to continue any kind of execution path in an elegant manner (as opposed to the previously mentioned status code return mechanism). I also think that exceptions make it possible to decouple errors from their handling a lot easier than the alternatives...

    It might help to think of the alternatives to exceptions (this isn't a definitive list, I'm curious to know how others might address the problem):

    • returning status codes (methods cannot return values, must use byref calls to update objects)
    • setting a global error flag by some mechanism
    • setting a local member variable and have a 'getStatus' type method that needs to be checked after every method


    I find that exceptions provide an elegant way for the error to be handled by the layer of your application that needs to handle it. It also allows multiple layers to react in different ways (if the exception is bubbled back up). For example, a transaction management layer may catch an exception and roll back the transaction, then bubble the exception further up where a UI layer can show a more friendly user error, instead of the UI layer needing to perform both operations (or, which might be worse, have the lower level layer know about its enclosing transaction).

    But one thing is for sure, it is definitely possible to abuse exceptions for doing things like event bubbling.

  13. #13
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    McGruff, use exception wrapping or chaining (see PEAR exception) to prevent encapsulation violations.

  14. #14
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kyberfabrikken
    The throwing function isn't breaking any encapsulation. If the caller wants to catch the exception, it can.
    Yes - you're right. I was wrong to say that exceptions automatically break encapsulation simply because object A doesn't have a reference to object B. I suppose exceptions are a kind of Observer mechanism built in to the language. Objects can choose to receive messages based on the message type rather than being registered with an observable. One possible niggle with that is that all exception messages are being broadcast on the same channel. If the message addressing goes wrong catchers could pick up exceptions which should have been caught elsewhere. That's not a reason not to use exceptions but maybe to be careful if there are many throws and catches.

    I do feel a bit like Dr Van Helsing at a party where I've just been introduced to a tall gentleman who wears a long, dark cloak, has a piercing stare and who casts no reflection in the mirror. I shouldn't jump to conclusions but I'm keeping my garlic close at hand.

    Quote Originally Posted by Selkirk
    use exception wrapping or chaining (see PEAR exception) to prevent encapsulation violations.
    Thanks Selkirk. Chaining/wrapping is a piece of the jigsaw which I was missing. I think I can see how this allows context to be added as exceptions bubble up but I'm still uncomfortable with the location where an error state is identified as an exceptional event.

    Quote Originally Posted by Tanus
    I wouldn't say it's made the 'decision' to abort the current execution path. Decisions usually imply that there's more than one option; I'd make the argument that exceptions make it possible to continue any kind of execution path in an elegant manner
    A throw() call cuts out a slice of code between the throw point and the catch point. The object which makes the throw() call doesn't know where the exception will be caught and so doesn't know exactly what slice of code will be dumped, but it is the one which decides to make the cut. There is no "goback" command - similar to break/continue in a loop - which would allow the catcher to make the decision:

    PHP Code:
        try {
            ...
            ...
        } catch(
    Foo $exception) {
            ...
            ...
            
    goback;
        } 
    That, I think, would remove the goto naughtiness turning throw/catch into a plain and simple Observer?

    The.. er.. little-known First Law of Code Thermodynamics means that if something falls into a wormhole entry point, something else must come back out. They can't be one-way only. With a "goto" but no "goback" the books are balanced by pulling some catcher logic through the wormhole in the other direction and dumping it in the thrower. Not the logic which decides how to handle the exceptional event but the logic which decides that some kind of thrower state is an exceptional, execution-path-altering event in the first place. If the catcher could choose to "goback" then the throw() call wouldn't carry this hidden meaning.

    However none of that would matter if you know the thrower class will only ever be used in the "drop everything now" case.

  15. #15
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    I suspect that what you are looking for is this,

    PHP Code:
    try {
            
    // ...
        
    } catch( QFront_Action_Controller_Exception $e ) {
            
    // ...
        
    finally ... {
            
    // ...
        

    As in Java, though lacking in PHP; The last clause would resolve the issues you are having, but I'm of the mind that as it stands, PHPs exceptions are just as capable anyways.

    Talking about wormholes, well they've not yet been proven to exist; Like Santa Clause really

  16. #16
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    One possible niggle with that is that all exception messages are being broadcast on the same channel. If the message addressing goes wrong catchers could pick up exceptions which should have been caught elsewhere. That's not a reason not to use exceptions but maybe to be careful if there are many throws and catches.
    That's why you shouldn't throw untyped exceptions:
    PHP Code:
    try {
      
    $juicer->squeeze();
    } catch (
    OutOfFruitException $ex) {
      
    // handle exception

    This will catch the typed OutOfFruitException, but let other exceptions fall through. Since we (presumably) have a way of handling that situation, we catch it, but if there's a more generic error -- like a NetworkTimeoutException or whatever, there's no way to handle it, and we let it bubble up and ultimately halt the application.

  17. #17
    SitePoint Addict n0other's Avatar
    Join Date
    Feb 2005
    Posts
    290
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, kyberfabrikken, I now know the reason behind throwing typed exceptions. But one question is still in mind, is it really worth it to make empty classes extending the base Exception, isn't there any other way to go around throwing custom exception without having a class for it? I might be talking nonsense, but the idea of having to load a file form disk and parse it just to have a typed exception scares me. Maybe one big class of exceptions would be better, but that's not so elegant..

  18. #18
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    The Netherlands
    Posts
    170
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    That's why you shouldn't throw untyped exceptions
    Typing is indeed an important concept IMO. At the risk of hijacking this thread: do you guys use SPL's exceptions to provide typing?

  19. #19
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I wouldn't worry too much about just having a file to contain a class extending PHPs own exception, which is the lesser of two evils,

    > Maybe one big class of exceptions would be better, but that's not so elegant..

    Which is not what you want

  20. #20
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by n0other View Post
    But one question is still in mind, is it really worth it to make empty classes extending the base Exception, isn't there any other way to go around throwing custom exception without having a class for it?
    That's just a mental barrier you have to overcome. Declaring an empty class doesn't take up any resources worth mentioning -- It's really just another way of declaring a constant.

    I'd normally declare the exception in the same file as the class throwing it, rather than in a separate file. I guess that's a matter of taste.

  21. #21
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    A throw() call cuts out a slice of code between the throw point and the catch point. The object which makes the throw() call doesn't know where the exception will be caught and so doesn't know exactly what slice of code will be dumped, but it is the one which decides to make the cut. There is no "goback" command - similar to break/continue in a loop - which would allow the catcher to make the decision:

    PHP Code:
        try {
            ...
            ...
        } catch(
    Foo $exception) {
            ...
            ...
            
    goback;
        } 
    That, I think, would remove the goto naughtiness turning throw/catch into a plain and simple Observer?
    I guess that could be seen as a litmus test for whether you're wanting to use an exception or not. If you're throwing an exception, you're stating that it is not possible to execute any of the following code because the current state is not valid for executing that code (an exceptional state).

    Hypothetically speaking, say you were performing some operation that required the use of a file. If that file wasn't able to be opened, you don't want to execute any of the code after that point, as it'd be using an invalid file resource. If you threw an exception, you'd never want to 'goback;' to that point after handling that exception to continue executing the code.

  22. #22
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That is the whole point of having the ability of exceptions, and their behaviour. Can't understand why people get hung up on it however; It's not rocket science, surely?

  23. #23
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tanus View Post
    I guess that could be seen as a litmus test for whether you're wanting to use an exception or not. If you're throwing an exception, you're stating that it is not possible to execute any of the following code because the current state is not valid for executing that code (an exceptional state).
    No, exceptions don't interrupt the code flow unconditionally. Firstly, an exception can be recoverable (actually, most of them are) and that's 'goback' (or 'retry' e.g. in Ruby) is for:

    Code:
    begin
    	ftp.connect
    rescue
    	if not ftp.passive then
    		ftp.passive = true
    		retry # go to 'begin'
    	end
    	show_error "Connect failed"
    end
    More important, php also lacks java's 'finally' blocks ('ensure' in ruby).

  24. #24
    SitePoint Wizard silver trophy Karl's Avatar
    Join Date
    Jul 1999
    Location
    Derbyshire, UK
    Posts
    4,411
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Exactly, I can't understand where people are getting so hung with exceptions.

    The whole point is that if you've raised an exception, then that means that the code after that point can't be executed in a way that would work - so it doesn't matter that you've stopped the current chain of execution. The same happens if you do it with return codes etc. apart from you're returning a code, and you've had to use an if block in the code that caused the error, to skip over the bits of code that wouldn't execute if you'd continued under the error situation.
    Karl Austin :: Profile :: KDA Web Services Ltd.
    Business Web Hosting :: Managed Dedicated Hosting
    Call 0800 542 9764 today and ask how we can help your business grow.

  25. #25
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I can explain better with something I'm working on now. It's a refactoring tool and there are a few things to do in the script before I can begin a refactoring op. One of these is to sync a working copy - an update and commit - so there's a clean revision to revert to if the refactoring messes up the working copy. Thus I'll need a Syncer class. If it can't ping a host, let's say it throws an exception. All well and good: I can't continue to do the refactoring if I can't sync. This is a genuine, show-stopping error.

    Later, I realise that Syncer would be handy in another shell script. I've got a pile of working copies to keep in sync and this will make them easier to manage. The script will loop through the list attempting to sync each in turn but if there's no ping to one of the repo hosts Syncer will throw a script-killing exception and that's that. Other working copies on ping-able hosts won't get updated.

    The precise problem which I'm tripping over is the controlling (catcher) class logic implicit in the throw() call. Put that back in its rightful place, by adding a goback/retry to the exception mechanism, and the issue goes away. Of course it may never arise in the first place unless you use the thrower class in multiple contexts.

    Does this make exceptions un-agile?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •