Issues

ZF-11805: Zend_Navigation_Page error messages don't contain enough information

Issue Type: Improvement Created: 2011-10-07T13:42:43.000+0000 Last Updated: 2012-05-31T23:44:21.000+0000 Status: Resolved Fix version(s): - 1.12.0 (27/Aug/12)

Reporter: monk e boy (monk.e.boy) Assignee: Frank Brückner (frosch) Tags: - Zend_Navigation

  • FixForZF1.12
  • state:patch-ready-for-review
  • zf-crteam-padraic
  • zf-crteam-priority
  • zf-crteam-review

Related issues: - ZF-11372

Attachments: - Page.php.patch

Description

Using a navigation.ini file, it is really easy to typo or make a mistake.

In Zend_Navigation_Page the exception 'Invalid argument: Unable to determine class to instantiate' on line 235 is really hard to fix. It should show the line that caused the error and why (e.g. no parent page, no container named 'blah' or something)

Comments

Posted by Frank Brückner (frosch) on 2011-10-07T14:23:54.000+0000

{quote}…why (e.g. no parent page, no container named 'blah' or something){quote} This has nothing to do with parent page or container.

<pre class="highlight">
throw new Zend_Navigation_Exception(
   'Invalid argument: Unable to determine class to instantiate '
   . '(URI page takes a option uri; MVC pages are defined using '
   . 'MVC parameters like action, controller, module, route or params)'
);

Posted by Frank Brückner (frosch) on 2011-10-07T14:38:36.000+0000

Another idea:

<pre class="highlight">
require_once 'Zend/Navigation/Exception.php';

$message = 'Invalid argument: Unable to determine class to instantiate';
if (isset($options['label'])) {
    $message .= ' (Label: ' . $options['label'] . ')';
}            

throw new Zend_Navigation_Exception($message);



<pre class="highlight">
Fatal error:
Uncaught exception 'Zend_Navigation_Exception' with message 'Invalid argument: Unable to determine class to instantiate (Label: Home)' in …

Posted by monk e boy (monk.e.boy) on 2011-10-10T14:36:52.000+0000

I find moving or renaming pages and missing one of the children (my navigation.ini file is 800+ lines long) is the most common error, e.g:

sales.pages.discounts.pages.category.pages.cms.pages.intro.label = Edit

then somewhere 'discounts' gets renamed to 'offers' then the above line throws:

Invalid argument: Unable to determine class to instantiate

because 'discounts' no longer exists... your solution would show the word 'Edit' which would be useful. Could we show the .ini file line number? Or anything more to help hunt down the offending change?

Posted by monk e boy (monk.e.boy) on 2011-10-10T14:43:16.000+0000

OK I just re-read my comment and it makes no sense - lol, say I have this:

sales.pages.discounts.label = Offers sales.pages.discounts.module = admin sales.pages.discounts.controller = offer sales.pages.discounts.action = index

... 100s of lines of ini file ...

sales.pages.discounts.pages.category.pages.cms.pages.intro.label = Edit sales.pages.discounts.pages.category.pages.cms.pages.intro.module = admin sales.pages.discounts.pages.category.pages.cms.pages.intro.controller = cms sales.pages.discounts.pages.category.pages.cms.pages.intro.action = editor

Then someone renames:

sales.pages.offers.label = Offers sales.pages.offers.module = admin sales.pages.offers.controller = offer sales.pages.offers.action = index

... then the following lines now throw errors:

sales.pages.discounts.pages.category.pages.cms.pages.intro.label = Edit sales.pages.discounts.pages.category.pages.cms.pages.intro.module = admin sales.pages.discounts.pages.category.pages.cms.pages.intro.controller = cms sales.pages.discounts.pages.category.pages.cms.pages.intro.action = editor

The app is run and we get that cryptic error message:

'Invalid argument: Unable to determine class to instantiate'

and the first place we start looking is in the lines of code we changed (which are correct and have no errors)

I assume that yaml navigation files don't have this problem?

Posted by Frank Brückner (frosch) on 2011-10-10T15:15:00.000+0000

Hi monk e boy, thanks for your feedback, but unfortunately there is no way to get the line number from the config file. All Zend_Config objects are converted to arrays and so there is no relation to the config file.

<pre class="highlight">
public function addPages($pages)
{
    if ($pages instanceof Zend_Config) {
        $pages = $pages->toArray();
    }

    // …

    foreach ($pages as $page) {
        $this->addPage($page);
    }

    // …
}



<pre class="highlight">
public static function factory($options)
{
    if ($options instanceof Zend_Config) {
        $options = $options->toArray();
    }

    // …

    $hasUri = isset($options['uri']);
    $hasMvc = isset($options['action']) || isset($options['controller']) ||
              isset($options['module']) || isset($options['route']);

    if ($hasMvc) {
        require_once 'Zend/Navigation/Page/Mvc.php';
        return new Zend_Navigation_Page_Mvc($options);
    } elseif ($hasUri) {
        require_once 'Zend/Navigation/Page/Uri.php';
        return new Zend_Navigation_Page_Uri($options);
    } else {
        require_once 'Zend/Navigation/Exception.php';
        
        $message = 'Invalid argument: Unable to determine class to instantiate';
        if (isset($options['label'])) {
            $message .= ' (Label: ' . $options['label'] . ')';
        }            
        
        throw new Zend_Navigation_Exception($message);
    }
}

{quote}I assume that yaml navigation files don't have this problem?{quote} This is only the syntax, because nothing needs to be written multiple times.

Example:

<pre class="highlight">
sales.pages.discounts.pages.category.pages.cms.pages.intro.label = Edit
sales.pages.discounts.pages.category.pages.cms.pages.intro.module = admin
sales.pages.discounts.pages.category.pages.cms.pages.intro.controller = cms
sales.pages.discounts.pages.category.pages.cms.pages.intro.action = editor



<pre class="highlight">
sales:
    pages:
        discounts:
            pages:
                category:
                    pages:
                        cms:
                            pages:
                                intro:
                                    label: Edit
                                    module: admin
                                    controller: cms
                                    action: editor

Posted by monk e boy (monk.e.boy) on 2011-10-11T10:55:12.000+0000

Would be brilliant if your last comment was in the documentation :) the yaml file looks a lot nicer for our front end devs to use.

Thanks for all your help :)

Posted by Frank Brückner (frosch) on 2011-10-11T15:04:18.000+0000

Tasks for this issue:

  • Extend the exception message (Zend_Navigation_Page::factory())
  • Add examples for INI, JSON and YAML to docs
  • Update xml example in the docs (syntax highlighting)

Posted by Frank Brückner (frosch) on 2011-11-14T20:44:00.000+0000

Fix and unit test added.

Posted by Frank Brückner (frosch) on 2011-11-14T22:42:49.000+0000

Patch for docs.

Posted by Adam Lundrigan (adamlundrigan) on 2012-05-31T23:44:20.000+0000

Fixed in trunk (1.12.0): r24854

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts