Save Time Debugging Custom Manager Pages

Learn the ins and outs—and how to skip a lot of mistakes—when debugging a MODX Custom Manager Pages.

By Bob Ray  |  November 22, 2021  |  3 min read
Save Time Debugging Custom Manager Pages

I just spent more hours than I care to admit debugging a MODX Custom Manager Page (CMP). I thought I would share a bit about the process, partly because the problem turned out to be so amazingly insidious, and partly because I learned some things that might help you debug a CMP of your own.

While adding CMP features to MyComponent, I created a fairly simple CMP as part of the Example project. The CMP has two tabs: The left one shows a grid with all the Snippets on the site and the right tab shows a Chunk grid.

Every time I rebuilt the project, I would clear the site cache and run the CMP. The Snippet grid always showed up empty. The grid was there, but there were no Snippets in it. The Chunk grid looked fine. I later learned that this only happened right after the cache was cleared, but I’m not sure knowing that would have helped me.

The first thing I did was to put a Reload button in the grid’s toolbar, which fired this function:

reloadSnippets: function () {
    this.getStore().baseParams = {
        action: 'mgr/snippet/getList'

That worked fine. All the Snippets showed up in the grid every time, which meant that my processor was fine. Looking back, I’m pretty sure that if I had cleared the site cache before clicking on the Reload button, it wouldn’t have worked, but again, I’m not sure that would have helped.

I spent the next several hours going over the JavaScript code, line by line, in every file I thought might have something to do with the problem. I compared the files with those of a number of other working CMPs. PhpStorm’s Compare Files was a big help, but I couldn’t find anything that looked the least bit suspicious. The Snippet grid code was identical to the Chunk grid code except for the processor called, and I knew the getlist processor was fine because, a) it worked some of the time, and b) it was essentially identical to the Chunk getlist processor.

Next, I got a little desperate and tried various wacky alterations to my JS code, none of which had any effect.

After much too long, I finally got smart and decided to take a look at the process in Chrome’s Developer Tools — something should have done much earlier.

After clearing the site cache, I pressed CTRL + SHIFT + I in Chrome and ran the CMP. With the Network tab selected, I could see that everything was executing in the right order, but there was an error in the console:

Uncaught SyntaxError: Unexpected token <

That made me think of the processor, since there were no < characters in the JavaScript code (which I knew was free of syntax errors, since PhpStorm didn’t find any and the Reload button worked). Processors don’t show up on Chrome’s Network tab, but the Connectors that communicate with them do. I found the call to connector.php and clicked on it.

In Chrome’s Developer Tools, clicking on a connector file name that has just executed opens up a new section with information on the Ajax request. Everything looked fine on the Headers tab. The right processor was being called with the right information. I already knew that it was returning a normal 200 (success) response (from the report on the Network tab). When I clicked on the Response tab, though, I got a little shock. Here’s a partial look at it:

( ! ) Notice: Undefined index: gallery.usecss_desc in C:\xampp\htdocs\addons\core\components\gallery\lexicon\en\ on line 58
Call Stack
# Time Memory Function Location

It should have looked something like this:


It looks like gibberish, but I’ve seen this before. It’s an extravagantly formatted E_NOTICE error from PHP. I have E_NOTICE errors turned on in my development environment (I wish every MODX Extra developer did). I had to scroll to the right to see the key part of it. You can also paste the code into a file and look at it in a browser. All the HTML will disappear and you’ll see a bright-orange, easy-to-read PHP notice. Here’s the important part:

Notice: Undefined index: gallery.usecss_desc

If I scrolled all the way to end of the response, I could see the JSON data that my processor returned. I felt like apologizing to the processor for doubting it.

Using PhpStorm’s Find in Path, I did a search of my entire MODX install (which includes all my Extras) looking for gallery.usecss_desc. After about 3 seconds, I could see that it only appeared in two places, both (Lexicon) files. Clicking on the first search result took me right to the offending line. Here it is, with the previous line for comparison:

$_lang['gallery.thumbzoomcrop_desc'] = 'Whether or not the thumbnail will be zoom-cropped.';

I changed it to this:

$_lang['gallery.usecss_desc'] = '';

The problem with my CMP disappeared. That leaves the question of what Gallery had to do with my CMP. The answer is: absolutely nothing. In fact, as if the error is not weird enough to begin with, according to Package Manager the Gallery Plugin is not installed on my site.

Here is my theory (which is my theory — it’s a theory, and it’s mine) about what was happening. When MODX handles a request and the cache is empty, one of the things it does is load the Lexicon. Apparently in some remote part of the MODX brain, the Gallery properties still exist and need Lexicon strings, so the left-over Gallery Lexicon file got included.

The PHP Syntax error in the Lexicon file triggered the E_NOTICE error message, which was then lurking in the output buffer, waiting for the request to finish. My processor’s output was tacked onto the error message in the buffer and the whole mess got returned to my CMP for processing. When the parser tried to decipher what was supposed to be pure JSON, it just threw up its hands and went out for a beer.

What Have We Learned Here?

First of all, when there is an intermittent problem with a program that makes Ajax requests, see if you can make the problem happen with a developer tool turned on and take a close look at all the connector.php responses. If I had done that, there wouldn’t be this pile of pulled-out hair all around my chair.

Second, get yourself a good code editor if you don’t have one already. Without PhpStorm, my tribulations would have lasted at least twice as long.

Finally, Plugins that are unrelated to the code you are developing can cause some very weird problems in MODX. I’ve seen this any number of times.

If you’re running your code outside of MODX, for example, and you load and initialize MODX, then call any MODX processors, the odds are good that some System Events will fire and some Plugins will execute. If the $modx->user and $modx->resource objects don’t exist (because your code doesn’t create them), things will go south in a hurry and you’ll have a devil of a time figuring out why.

Remember the MODX upgrade that updated the hashing method for user passwords? Any Plugin that fired on a user save event could crash that install. One of my Extras did that until I fixed it, and if it weren’t for a lucky accident, I never would have known about the problem with my Extra.

Even inside of MODX, remember that there are Plugins that can step in and modify things whenever you perform a Manager action like saving a Resource, Element, or User. They can interfere with whatever you’re trying to do and make your life very miserable for hours on end.

I should mention that most MODX Plugins are well-behaved and unlikely to cause any problems, but when everything else fails, start disabling your Plugins.

Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.