Grav: extract error during upgrade installation

Created on 15 Mar 2018  路  18Comments  路  Source: getgrav/grav

following error occurs:

Preparing to upgrade to v1.4.1..
  |- Downloading upgrade [3.28M]...   100%
  |- Installing upgrade...    error                             
  |  '- An error occurred while extracting the package
  '- Installation failed or aborted.

i tried --verbose, set errors to true in system.yaml, nothing inside the logs, only "An error occurred while extracting the package".

has anyone an idea how i can get decent error information, what's failing during extraction?

Thanks!

Edit: I think it's a permission problem, but i dont know how to get the tmp path where the files are extracted to ...

question

All 18 comments

The code where this can be set is in the Grav\Common\GPM\Installer.php:

public static function unZip($zip_file, $destination)
    {
        $zip = new \ZipArchive();
        $archive = $zip->open($zip_file);

        if ($archive === true) {
            Folder::mkdir($destination);

            $unzip = $zip->extractTo($destination);


            if (!$unzip) {
                self::$error = self::ZIP_EXTRACT_ERROR;
                Folder::delete($destination);
                $zip->close();
                return false;
            }

            $package_folder_name = preg_replace('#\./$#', '', $zip->getNameIndex(0));
            $zip->close();
            $extracted_folder = $destination . '/' . $package_folder_name;

            return $extracted_folder;
        }

        self::$error = self::ZIP_EXTRACT_ERROR;

Basically, all we're doing is trying to open the zip file, if that archive is not true, this error gets set.

The temp folder used is $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); so this is usually tmp/ in your Grav installation.

I have got a Pull Requst where i've added more verbose error code handling, perhaps you could test with that?

Thanks for the fast answer! That PR looks promising, will try that :)

I already tried to debug the Grav\Common\GPM\Installer.php but i didn't succeed in getting some additional debug output into the shell. Are the cli scripts cached in some way? Or, is there a simple way to dump some debug information triggered from the Grav\Common\GPM\Installer.php to the shell, when using bin/gpm selfupgrade?

You can dump to the log file by inserting:

Grav::instance()['log']->notice('My notice message');

in the code. Or if you in GPM, you can simply echo() stuff and it will display in the console as output.

Thanks, that was the information i was looking for!

I tested Grav::instance()['log']->notice('My notice message');, it doesn't create a log file under /logs ...
And echo() doesn't work for displaying debug infomation in the shell ...
-> Seems the Installer-Msg shell formatting somehow overlays the echo() output

So i have no idea how to debug the problem ...

If i test with the PR, i get:

PHP Fatal error:  Uncaught Error: Class 'Grav\Common\GPM\ZipArchive' not found in /var/www/sophora-docs/system/src/Grav/Common/GPM/Installer.php:206
Stack trace:
#0 /var/www/sophora-docs/system/src/Grav/Common/GPM/Installer.php(193): Grav\Common\GPM\Installer::getZipError(19)
#1 /var/www/sophora-docs/system/src/Grav/Common/GPM/Installer.php(97): Grav\Common\GPM\Installer::unZip('/var/www/sophor...', '/var/www/sophor...')
#2 /var/www/sophora-docs/system/src/Grav/Console/Gpm/SelfupgradeCommand.php(219): Grav\Common\GPM\Installer::install('/var/www/sophor...', '/var/www/sophor...', Array)
#3 /var/www/sophora-docs/system/src/Grav/Console/Gpm/SelfupgradeCommand.php(177): Grav\Console\Gpm\SelfupgradeCommand->upgrade()
#4 /var/www/sophora-docs/system/src/Grav/Console/ConsoleCommand.php(29): Grav\Console\Gpm\SelfupgradeCommand->serve()
#5 /var/www/sophora-docs/vendor/symfony/console/Command/Command.php(266): Grav\Console\ConsoleCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ in /var/www/sophora-docs/system/src/Grav/Common/GPM/Installer.php on line 206

If i change ZipArchive::ER_EXISTS to \ZipArchive::ER_EXISTS, i get:

Preparing to upgrade to v1.4.2..
  |- Downloading upgrade [3.35M]...   100%
  |- Installing upgrade...    ok                             
  '- Success! 

But the update is not installed ...

Ok, that lack of \ was a legitimate issue... fixed in develop btw.

The face you get a success is very strange. Did you manage to add some logging statements to track down where things are going wonky?

Did you manage to add some logging statements to track down where things are going wonky?

Not really, tryin again now ... It's installed in a corporate network, so i can only investigate in the beginning of each week.

Ah, debugging works now and i found out that the errorcode 19 is returned from ZipArchive::open ... dont know what it means yet, still investigating ...

Edit: 19 stands for \ZipArchive::ER_NOZIP, so there seems to a problem in the unZip function in Grav\Common\GPM\Installer.php

Ok, so the "success but no success" error is caused by:

-        self::$error = self::ZIP_EXTRACT_ERROR; // -> returns integer
+        self::$error = self::getZipError($archive); // -> returns error string

The function that calls the Installer is expecting an integer error, here

So the PR needs a bit refactoring :)

Investigating now what the "Not a zip archive." error means in my case.

if i run unzip grav-update-v1.4.2.zip:
it generates following output:

Archive:  grav-update-v1.4.2.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of grav-update-v1.4.2.zip or
        grav-update-v1.4.2.zip.zip, and cannot find grav-update-v1.4.2.zip.ZIP, period.

the download with wget works fine, taking a closer look in the Response Class ...

Ok, so seems to be the corporate firewall, wget is just more robust than curl, tested everything outside the corporate network and everything works fine.

Closing here ...

@rhukster Is there some way for me to make some changes to the #1922 PR, then i could fix those bugs mentioned earlier ... do you have to assign me? or is there another way ...

@jens-t simply edit the file on grav develop branch directly in GitHub. Then when comitting it creates a fork and pull request automatically.

ok, thanks for the info! (didn't recognize the PR is already merged) will make a new PR ...

@jens-t aside from all the changes that happened and your PR, what exactly was the issue for the ZIP for failing?
The fact you were originally getting the error An error occurred while extracting the package, clearly states that something on your end was preventing the unzip to work.
What was it? I do not believe any of the changes happening in here have resolved the problem you originally had as these are just better messaging output changes more than anything else.

@jens-t aside from all the changes that happened and your PR, what exactly was the issue for the ZIP for failing?

Yeah, as mentioned above the problem was the corporate firewall, which caused a connection break during download. This produced a corrupt zip archive.

I first tested the download with wget and it worked well, thats why i thought it was something else. And startet debugging the installer, used the zip error msg pr as help and found out about the zip error bug. But found no problem with the installer. Then i started to debug the response class and noticed the connection break problem with curl. So yes, the zip error message bug wasn't causing my problem, i just discovered it during debugging ...

Because of the fact that the zip error message was assigned to self::error and not the error code, the condition discussed in the related pr failed, and the installer showed success, where it should have showed an unzip error.

The pr was meant as a fix for this false success notice. But es you explained in the pr, the condition is not the problem, it's the string error assigned to self::error when it should be an integer error code. Which was also my first thought, described it some comments above.

Ok good to know.
I actually reverted all the changes and I'm going to close your PR. I approached it differently while integrating Andy's more meaningful zip error messages.

So now if it happens again you will get the reason as to why the message failed:

Preparing to upgrade to v1.4.2..
  |- Downloading upgrade [3.35M]...   100%
  |- Installing upgrade...    error
  |  '- Unable to extract the package. Not a zip archive.
  '- Installation failed or aborted.

Note the Not a zip archive message.

You can see my changes @ https://github.com/getgrav/grav/commit/3248b979975ebda31ca7316a7a7dc36da05c8d72

Thanks for helping debugging this!

Thanks for helping debugging this!

No problem!

You can see my changes @ 3248b97

Yes! Divide these error codes in two different vars is the solution i already thought about, since it's more an additional error message. Good to know how you approached this :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ekumlin picture ekumlin  路  37Comments

gizmecano picture gizmecano  路  17Comments

gszathmari picture gszathmari  路  16Comments

ursbraem picture ursbraem  路  29Comments

ThinkDevStudios picture ThinkDevStudios  路  17Comments