4

I have a problem with symfony and apparently twig. I've been working on a project for some time, and as I was about to make a new release (by uploading everything througn ftp, following this : https://medium.com/@runawaycoin/deploying-symfony-4-application-to-shared-hosting-with-just-ftp-access-e65d2c5e0e3d).

Just before doing the upload, I discover that the application stopped working a day before. I start to search for the issue, but there wasn't anything in the logs. I decide to reupload everything and clear the cache, in case that could be the problem, but still nothing, just a 500 error.

I then enable the debug, and get the error :

The autoloader expected class "Twig\Extension\AbstractExtension" to be defined in file ".../symfony/vendor/composer/../twig/twig/src/Extension/AbstractExtension.php". The file was found but the class was not in it, the class name or namespace probably has a typo.

I tried everything I could find online, but the only one who had a similar problem solved it by adding twig/extensions, but this does not solve it either.

I don't get at all what may have happened, but this problem seemed to have appeared with no reason, and without any file change.

The application did work before, and still works offline.

Here's the code of the AbstractExtension.php, which is the same as on the twigphp/twig repo :

<?php

namespace Twig\Extension;

class_exists('Twig_Extension');

if (\false) {
    class AbstractExtension extends \Twig_Extension
    {
    }
}

PS : this if false sounds weird but is the same as online so i don't get it

EDIT : here's the log as text :

(1/1) RuntimeException
The autoloader expected class "Twig\Extension\AbstractExtension" to be defined in file "/home/homeviewcx/symfony/vendor/composer/../twig/twig/src/Extension/AbstractExtension.php". The file was found but the class was not in it, the class name or namespace probably has a typo.

in DebugClassLoader.php line 288
at DebugClassLoader->checkClass('Twig\\Extension\\AbstractExtension', '/home/homeviewcx/symfony/vendor/composer/../twig/twig/src/Extension/AbstractExtension.php')
in DebugClassLoader.php line 159
at DebugClassLoader->loadClass('Twig\\Extension\\AbstractExtension')
at spl_autoload_call('Twig\\Extension\\AbstractExtension')
in CsrfExtension.php line 21
at require('/home/homeviewcx/symfony/vendor/symfony/twig-bridge/Extension/CsrfExtension.php')
in DebugClassLoader.php line 145
at DebugClassLoader->loadClass('Symfony\\Bridge\\Twig\\Extension\\CsrfExtension')
at spl_autoload_call('Symfony\\Bridge\\Twig\\Extension\\CsrfExtension')
at class_exists('Symfony\\Bridge\\Twig\\Extension\\CsrfExtension')
in FrameworkExtension.php line 1240
at FrameworkExtension->registerSecurityCsrfConfiguration(array('enabled' => true), object(MergeExtensionConfigurationContainerBuilder), object(XmlFileLoader))
in FrameworkExtension.php line 205
at FrameworkExtension->load(array(array('router' => array('resource' => 'kernel::loadRoutes', 'type' => 'service')), array('secret' => 'env_d3d895c31330f4ea_APP_SECRET_dd4bd60cef72a43e4dea38ee2ba60137', 'session' => array('handler_id' => null), 'php_errors' => array('log' => true), 'cache' => null), array('router' => array('strict_requirements' => null)), array('default_locale' => 'en', 'translator' => array('paths' => array('/home/homeviewcx/symfony/translations'), 'fallbacks' => array('en'))), array('validation' => array('email_validation_mode' => 'html5')), array('cache' => array('pools' => array('doctrine.result_cache_pool' => array('adapter' => 'cache.app'), 'doctrine.system_cache_pool' => array('adapter' => 'cache.system'))))), object(MergeExtensionConfigurationContainerBuilder))
in MergeExtensionConfigurationPass.php line 76
at MergeExtensionConfigurationPass->process(object(ContainerBuilder))
in MergeExtensionConfigurationPass.php line 39
at MergeExtensionConfigurationPass->process(object(ContainerBuilder))
in Compiler.php line 95
at Compiler->compile(object(ContainerBuilder))
in ContainerBuilder.php line 746
at ContainerBuilder->compile()
in Kernel.php line 519
at Kernel->initializeContainer()
in Kernel.php line 123
at Kernel->boot()
in Kernel.php line 183
at Kernel->handle(object(Request))
in app.php line 50

here's my composer.json :

    {
    "type": "project",
    "license": "proprietary",
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "sensio/framework-extra-bundle": "^5.1",
        "symfony/apache-pack": "^1.0",
        "symfony/asset": "^4.1",
        "symfony/config": "^4.1",
        "symfony/console": "^4.1",
        "symfony/dependency-injection": "^4.1",
        "symfony/expression-language": "^4.1",
        "symfony/flex": "^1.0",
        "symfony/form": "^4.1",
        "symfony/framework-bundle": "^4.1",
        "symfony/lts": "^4@dev",
        "symfony/monolog-bundle": "^3.1",
        "symfony/orm-pack": "*",
        "symfony/process": "^4.1",
        "symfony/security-bundle": "^4.1",
        "symfony/serializer-pack": "*",
        "symfony/swiftmailer-bundle": "^3.1",
        "symfony/twig-bundle": "^4.1",
        "symfony/validator": "^4.1",
        "symfony/web-link": "^4.1",
        "symfony/yaml": "^4.1"
    },
    "require-dev": {
        "symfony/debug-pack": "*",
        "symfony/dotenv": "^4.1",
        "symfony/maker-bundle": "^1.0",
        "symfony/profiler-pack": "*",
        "symfony/test-pack": "^1.0",
        "symfony/web-server-bundle": "^4.1"
    },
    "config": {
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "replace": {
        "symfony/polyfill-iconv": "*",
        "symfony/polyfill-php71": "*",
        "symfony/polyfill-php70": "*",
        "symfony/polyfill-php56": "*"
    },
    "scripts": {
        "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ],
        "prod": [
          "SET APP_ENV=prod",
          "composer install --no-dev --optimize-autoloader",
          "composer dump-autoload --optimize --no-dev --classmap-authoritative"
        ],
        "dev": [
          "SET APP_ENV=dev",
          "composer install"
        ]
    },
    "conflict": {
        "symfony/symfony": "*"
    },
    "extra": {
        "symfony": {
            "allow-contrib": false
        }
    }
}

PS: I'm personally not extending the AbstractExtension class anywhere (nor any other twig classes), and haven't touched the container compiler either (still relatively new here), but yes, that might be it

  • 2
    Where did you get that if (\false) part from? It doesn't just sound weird, it's the exact cause of the problem. Also, class_exists doesn't make much sense where it is. – Stratadox Sep 15 '18 at 13:43
  • found it there and on my server : https://github.com/twigphp/Twig/blob/2.x/src/Extension/AbstractExtension.php – Etienne Desrousseaux Sep 15 '18 at 13:52
  • I did more search, they changed require '...' to class exists in june 2017, so I don't think that could explain why I suddenly get the error – Etienne Desrousseaux Sep 15 '18 at 13:53
  • Right, my bad. What does your composer.json say about autoloading? – Stratadox Sep 15 '18 at 14:07
  • I guess that's it : "autoload": { "psr-4": { "App\\": "src/" } } – Etienne Desrousseaux Sep 15 '18 at 14:14
  • Are you sure the code worked before? As far as I can tell, having if (false) around a class definition makes php not define the class - that's also exactly what the error is telling us. The best thing to do is probably to simply inherit from `Twig_Extension` instead of `AbstractExtension`. – Stratadox Sep 16 '18 at 15:38
  • The thing is this isn't my code, that's twig's code... Also, yes I'm sure it worked before, but symfony may have updated twig from 2.4.8 to 2.5 or something, but I can't tell anything about this... – Etienne Desrousseaux Sep 16 '18 at 20:04
  • I agree, it's super weird – Etienne Desrousseaux Sep 16 '18 at 20:04
  • The thing is, that part of the twig code simply doesn't work. It's there as a notice, like "hey, this is how we're going to do it" but it simply doesn't work yet. If *your* code didn't start using this not-yet-supported class, maybe one of your dependencies does? I'd do a global search on your own codebase first though, anything that extends from AbstractExtension could be the cause of the problem. – Stratadox Sep 16 '18 at 20:10
  • I don't extend it anywhere, and can't find it being used anywhere either, and it appears to be on all routes... The error happens in the kernel->handleRequest function, so my guess is that the class is being loaded before the route is being handled... – Etienne Desrousseaux Sep 17 '18 at 07:19
  • out of despair, i'm starting to rewrite everything using if class exists, and the error shifts files, so i guess it's working... I'm still gonna ask directly on the github – Etienne Desrousseaux Sep 17 '18 at 08:33
  • I also did revert to the old code, but doesn't help either.... – Etienne Desrousseaux Sep 17 '18 at 10:17
  • I added the full error here : https://github.com/twigphp/Twig/issues/2747 – Etienne Desrousseaux Sep 17 '18 at 18:35
  • Could you add the text of the full error to your question? (Not as image but as text, makes it doable to copy/paste and search) – Stratadox Sep 17 '18 at 19:20
  • Also, when is the first moment you receive the error? When trying to view a page or even before that? – Stratadox Sep 17 '18 at 19:23
  • "the error shifts files" -> wait a sec, the error just "goes to the next class"? In that case, it could simply be some process that tries to autoload every class in a slightly naive manner. – Stratadox Sep 17 '18 at 19:57
  • Actually I think your composer.json might be more useful than error logs at this point. I don't have a clear-cut solution for you (yet?) but I have a solid idea of what's going wrong: one of the recently updated dependencies of your project detects that `AbstractExtension` (and/or `Profile`) is a class and tries to autoload it, probably to generate some kind of cache. While autoloading, the file is found but because of the if false, there is no class loaded. The big question is: which tool triggers the autoloading? – Stratadox Sep 18 '18 at 22:31
  • 1
    The problem is probably not in symfony itself - not directly at least - otherwise many more people would have had the same problem and it'd be resolved. Given that your project is still functional in your local development environment, the problem could potentially be triggered somewhere when symfony [compiles the container](https://symfony.com/doc/current/components/dependency_injection/compilation.html), though. – Stratadox Sep 18 '18 at 22:37
  • It's not a satisfactory answer yet, but this is the direction I'd be searching in. Could you post the contents of your dependency container configuration? – Stratadox Sep 18 '18 at 22:39
  • From [what I read](https://stackoverflow.com/questions/47446199/symfony-3-twig-extension-abstractextension-not-found-error-in-production-mode) it could just be a matter of running `composer require twig/extensions`. – Stratadox Sep 18 '18 at 22:55
  • It might also just be a problem with composer; in which case you may want to remove your `vendor` directory and rerun `composer install`. – Stratadox Sep 18 '18 at 22:59
  • 1
    For future reference, extending AbstractExtension in the wild will actually work because of the class_alias [here](https://github.com/twigphp/Twig/blob/2.x/lib/Twig/Extension.php#L45). – Stratadox Sep 18 '18 at 23:04
  • I've added the log and the composer json on the thread, but had to remove the link. thanks for looking into the problem, I'm about 10 days to beta release and haven't bee able to get anything done in almost a week due to this. I'll try the require and re running the composer install, but it didn't help the first time I tried it... – Etienne Desrousseaux Sep 19 '18 at 07:11
  • What exactly do you mean by `before doing the upload` ... `stopped working a day before` ... `reupload everything`? That part sounds a bit vague. Also could you confirm that you've *deleted* the entire vendor directory and ran `composer install` again? – Stratadox Sep 19 '18 at 16:40
  • the app was already online, and my brother informed me there was a bug which wasnt there a few days before. As I had made some changes since the last upload, I decide to just re upload everything without checking what the error was, and it's at that point I discovered this error, which stayed there since. I do confirm that I deleted the vendor, both locally and remotely, ran composer install, and reuploaded it – Etienne Desrousseaux Sep 19 '18 at 19:00
  • Have you tried https://stackoverflow.com/a/49150533/4954580 ? (manually delete all vendors files and then running composer install or update). I got that error a couple of times, don't remember exactly how I solved it, but it has to do with composer update or install. – Roubi Sep 19 '18 at 20:30
  • did, but I'll do it again until it somehow fixes itself... gotta keep faith... :) – Etienne Desrousseaux Sep 19 '18 at 20:37
  • @Etienne Desrousseaux if the posted answer helped you solve the problem, please mark it as accepted (in which case I can award the bounty) - if not, please comment with a confirmation that you've tried the steps of the answer and the result it produced, so that other people can try and help. – Stratadox Sep 23 '18 at 17:11

1 Answers1

3

Looking at the commit that caused the error here :

https://github.com/twigphp/Twig/commit/2c174e4015dcfdcb4f39d004e3b1aeccae77aa25#diff-d2944cb9ff29770359c04590530f931aL5

The only change is the way the class is expected to be loaded, since class_exists('Twig_Extension') will call __autoload() thus the class is expected to be already called at this stage.

It looks like you already updated your dependencies, but did you clear the cache ? Since the problem is not available locally (works fine on dev), on the issue is only on your server (app runing in prod mode) symfony could be still using the old cache which explain the error.

If that's the case, you will need to refresh the cache on your server by running:

php bin/console cache:clear --no-warmup --env=prod

mrbm
  • 2,164
  • 12
  • 11
  • @Etienne Desrousseaux if this answer helped you solve the problem, please mark it as accepted (in which case I can award the bounty) - if not, please comment with a confirmation that you've tried the steps of the answer and the result it produced, so that other people can try and help. – Stratadox Sep 23 '18 at 17:10
  • sorry, I've been busy this weekend :/ The problem is that I can't clear the server cache using commands since I don't have access to the server console (I did however remove the cache by hand) Also, the older versions are working fine when re uploaded so I there should be an error with my code... – Etienne Desrousseaux Sep 25 '18 at 07:08
  • how did you proceed to remove the cache by hand ? – mrbm Sep 25 '18 at 15:50
  • Alright, I re deleted everything including the var file and re uploaded the last version and magic happens, it behaves normally again – Etienne Desrousseaux Sep 26 '18 at 07:25
  • oopsi, sorry but the error came back -_- I'll keep trying but do you know how I could properly clear the cache on the server pls? deleting everything doesn't seem to be the solution here – Etienne Desrousseaux Sep 26 '18 at 08:11
  • Maybe you can take a look at [this solution](https://stackoverflow.com/questions/10815962/what-is-the-best-way-to-clean-the-cache-without-running-the-console-command) - not the prettiest but simple and effective. – Stratadox Sep 26 '18 at 14:32
  • Given that it worked again (albeit temporarily) I'll consider this answer as beneficial, and award the bounty before its expiry. – Stratadox Sep 26 '18 at 14:53