[Solar-talk] Change to Solar_Controller_Page::fetch()

Travis Swicegood development at domain51.com
Tue Jan 2 11:10:06 PST 2007


Hey all,

Trac is down (already notified everybody), and I want to get this down 
somewhere before I forget about it, so here it is for public consumption...

I'm thinking it'd be useful for _postRun() to run even if _forward() 
throws an exception.  That gives you the ability to recover to something 
more useful than an exception at the app level.  This is especially 
important if you treat _preRun()/_postRun() like setup()/teardown() in 
unit tests where they do something that alters the environment or just 
tracks it.

A few examples might be:
* In _preRun() you start a logger that logs when an application starts 
and in _postRun() you want to mark that it ended even if it wasn't 
successful.
* On errors, you wanted each app to do something specific (i.e., blogs 
might error and email the webmaster while rss reader might email the 
webmaster of the rss feed, or just log an invalid return)
* Clean-up any temp files directly instead of waiting on PHP garbage 
collection
* Setup a render so the app always renders something - i.e. - "The blog 
server is unavailable at this time"


Anyhow, I did a little tweaking and have the following that I believe 
would work well with Solar.  It does change the behavior because 
_postRun() would always get called.  It adds a new protected call 
_exceptionThrow that should always be false unless an exception was 
thrown by something inside _forward().  That gives you a way to 
determine if _postRun() is working on a successful entry or if it should 
just be doing clean-up.

Here's the code.  Thoughts and comments are welcome:

    /**
     *
     * If not false, this contains an exception thrown during _forward()
     *
     * @var false|Exception
     *
     * @see fetch()
     *
     */
    protected $_exceptionThrown = false;

    public function fetch($spec = null)
    {
        // load action, info, and query properties
        $this->_load($spec);

        // prerun hook
        $this->_preRun();
        
        try {
            // action chain, with pre- and post-action hooks
           $this->_forward($this->_action, $this->_info);

           // postrun hook
           $this->_postRun()
        } catch (Exception $e) {
            // put caught exception in _exceptionThrow so _postRun()
            // is aware of it
            $this->_exceptionThrow = $e;

            // postrun hook
            $this->_postRun();

            // if _postRun() did not change _exceptionThrown, re-throw
            // it so it can continue to bubble up
            if ($this->_exceptionThrown !== false) {
                throw $this->_exceptionThrow;
            }
        }

        // render the view and layout, with pre- and post-render hooks
        return $this->_render();
    }


-Travis


More information about the solar-talk mailing list