Return both virtual pages and error message

Hi there,

I’m using a page model (below) to create virtual pages. I create pages by fetching a .xml file with some data. I’m using Data::read() to read the .xml file. I want to catch the error message if this steps fails and then show a message on page render. Is there a way I can pass/return $error to the controller or the page directly but also return the other “working” pages at the same time? Like what I would usually do inside a controller?

I’d like to inform the user that one of the “scanned” files could not be read but still return all working virtual pages if that makes sense.

<?php

use Kirby\Data\Data;
use Kirby\Filesystem\F;

class HomePage extends Page
{
    public function children()
    {

        if ($this->children instanceof Pages) {
            return $this->children;
        }

        $naslist            = [];
        $pages            = [];
        $basepath       = option('nas.root.path');
        $error              = null;
        
        /**
         * Scan $basepath and build an array of all subdirectories.
         * Each subdirectory represends a NAS
         */
        $naslist = array_values(array_diff(scandir($basepath), array('..', '.')));

        /**
         * Loop through all detected subdirectories
         * and create virtual pages for each NAS
         */
        foreach ($naslist as $key => $nas) {

            $path       = $basepath . $nas;
            $xmlfile    = $path . '/' . $nas . '.xml';
            
            // Let's make sure that this NAS has the {NAS_NAME}.xml file
            if(F::exists($xmlfile)) {

                try {
                    $xml = Data::read($xmlfile);
        
                    $pages[] = [
                        'slug'     => Str::slug($nas),
                        'num'      => $key+1,
                        'template' => 'nas',
                        'model'    => 'nas',
                        'content'  => [
                            'title'         => $nas,
                            ...
                        ]
                    ];
                } catch (Exception $e) {
                    $error = $e->getMessage();
                }
            }
        }

        return Pages::factory($pages, $this);
    }
}

Where do you want to inform the user?

Method can only return the children and nothing else. You also don’t want to throw an error.

What you could do is for example, log an error to some log file, then display these errors somewhere.

Ideally I want to display a “banner” notifying that one or multiple .xml files contain invalid data within the home template.

I guess I could write it to a logfile or some sort… but I was hoping there might be a different way.

I wonder what you were thinking of.

The method has to return a children collection, so it cannot return anything else or anything on top.

So you can either throw an exception, in which case you wouldn’t get your children back.

Or you log the errors somewhere (file, cookie, session, database, php error logs), and then read the information from there. PHP errror logs don’t really lend itself for the purpose, though, as they would contain to much different information. So that leaves you with the rest.

Well I didn’t know how to approach this hence I reached out if there’s a method I could not think of.
But I think I’ll go with the .log approach. Thank you for your thoughts @texnixe Appreciated!