404 Only on first hit of a page

Hello all,
I’ve a strange issue that seems to have developed but I’m not sure where from or what is causing it.

Basically after clearing cache the first hit to any page, including the homepage will return a 404 page.

Every subsequent call to the website the page will be displayed correctly.

Has anybody else had anything similar or have any tips as to what to look for, I’ve been looking at it for a while and tried disabling and reinstalling various plugins but nothing seems to make a difference.

Best,
Adrian

Hi @adrianw
Is this a live hosted) server or development server (local) that the problem is occuring.

Have you tried to run the site locally and see if the issue is happening.
Can you paste any log file errors (apache and grav (\logs\grav.log)

We might be able help diagnose a bit further from there , also if you can provide your current php and grav version for reference :slight_smile:

hi @spamhater

Unfortunately there’s no errors on any logs, it just jumps straight to the 404 on first hit after cache is cleared all latest version of Grav 1.7.16 plus plugins, Php running 7.3

It’s happening on both live and local versions, it strangely seems to have something to do with a static function used to populate data-options@ for forms I’m just narrowing it down a little further.

maybe as quick fix is to turn the forms yaml and disable caching on that form,

cache_enable: false

possibility to also run the

 bin/grav yamllinter 

to see if that picks up any anomalies.

If you want to try and post the blueprint on here, feel free and we can try and recreate the issue

Otherwise process of elimination of the blueprint and see if you can find the point of error. Do feel free to go to the discord channel and drop the question there, if you are happy to share the blueprint and see if they can identify any issue :slight_smile:

ok I’ve narrowed it down to a call, that I’, wondering if calling it early that might upset something.

So I have really simplified the function that data-options@ is calling to just
$grav = Grav::instance();
$page = $grav[‘page’];
return[];

The simple act of $page = $grav[‘page’] seems to upset everything, I’ve noticed that the $page returned is the system notfound.md

Could it be that call $grav[‘page’] too early breaks the routing, or causes the a different page to be built?

I check yamlinter, no issues and forms are all cache disabled

what I’ve done is added

  $routes = $grav['pages']->routes();
  if(!$routes) {
    return null;
  }

to my original routine to check if routes have been setup, they aren’t on the first call but are subsequently, before asking for the current page. That seems to have fixed it for me.

1 Like

Maybe because of the naming convention, with grav referring to pages and page as variables, it also worth staying clear of them as variable names just in case.

Old school programming
$page = …
and go for
$mypage =
to keep things clear.

I am not the best on oops and getting my hands really dirty with the api

but grav::instance seems to be deprecated and refers with a parameter for languages alot of the api refers to getInstance() instead.

This is sample of code from grav latest core

     /**
     * Return the Grav instance. Create it if it's not already instanced
     *
     * @param array $values
     * @return Grav
     */
    public static function instance(array $values = [])
    {
        if (null === self::$instance) {
            self::$instance = static::load($values);
        } elseif ($values) {
            $instance = self::$instance;
            foreach ($values as $key => $value) {
                $instance->offsetSet($key, $value);
            }
        }

        return self::$instance;
    }

I presume your blueprint is basically trying to display a list a of pages / all pages

It seems standard practice to check the parameter for existing data and then create the instance.

It is a big hard knowing only a snap shot of what your trying to do, but people like @pamtbaau will probably able to advise further , on best practises but I am sure he will require a bit more info (blueprint, function code etc, aim of functionality to be achieved)

@adrianw, I can reproduce your observation of a 404 error when cache has been cleared.

It is indeed caused by the call $page = $grav['page'].

When the page is being called after invalidating the cache, the static method for the form is being called before the pages are being initialized. When calling $page = $grav['page'] in the static method, there is no page yet known to Grav. That might somehow “confuse” Grav.

On subsequent calls, all pages have already been initialized.

I don’t think the 404 should happen though. You might consider opening a call on Github.

1 Like

@pamtbaau I’m happy you were able to replicate it and it wasn;t just some quirk of my local system.

What I was trying to do is minimise the load of the dynamic options function, the forms have a large amount of dynamic data.

The system calls the static function multiple times on every page load regardless of it being a form or not which was quite a large overhead, so my thought was to check and allow the build to go ahead only if the page being displayed was a form.

@adrianw, Again, I can confirm your observation that the static method is being called on every page request, even if the page doesn’t have a form…

This is not what I would expect and I’ve created an issue for the Form plugin.

As a workaround, try the following:

public static function myMethod()
{
    $grav = Grav::instance();
    $uri = $grav['uri'];
    $route = $uri->route();

    if ($route === 'expected-route') {
        // do useful things
        return 'useful data';
    }
}

In case you want to store the route(s) in the config file of the plugin use for example:

$routes = $grav['config']->get('plugins.yourplugin.routes', []);

Thanks @pamtbaau yes it came as a surprise to me too, thanks for the idea, unfortunately I can’t go down the uri method as there’s quite a number of different forms on different uri’s and the client can create them without me being able to change the underlying code, hence my idea of checking if a page contained any forms.
I’ve found a workaround I can use for now which I showed above, which is to check if the pages routes have been setup before I check if the page has forms.

Thanks for your help in this matter.