quicksilver-examples icon indicating copy to clipboard operation
quicksilver-examples copied to clipboard

False positive quicksilver status on passthru

Open marfillaster opened this issue 4 years ago • 10 comments

Issue Description:

The passthru usages will result in a false positive if the called command returns with non-zero exit code.

Suggested Resolution:

Check &$return_var value and raise an error to propagate the error to the calling quicksilver script.

$cmd = 'wp search-replace "://test-example.pantheonsite.io" "://example.com" --all-tables ';
passthru($cmd . ' 2>&1', $exit);
if (0 !== $exit) {
  trigger_error(sprintf('Command "%s" exit status: %s', $cmd, $exit), E_USER_ERROR);
}

marfillaster avatar May 06 '20 11:05 marfillaster

CC @sugaroverflow

alexfornuto avatar May 11 '20 15:05 alexfornuto

Hi @marfillaster thank you for opening this issue! I'm sorry, I'm not sure I understand the issue here - could you walk me through the false positive error that occurs?

My understanding of the passthru command was that we don't need to worry about the return value because we're just outputting to the browser.

sugaroverflow avatar May 14 '20 19:05 sugaroverflow

Hi Fatima,

Some customers are using passthru to invoke drush/wp cli commands in quicksilver during deployment. A failed run can result to adverse effect. Examples below:

  • drush updatedb - failed db migration means possible missing column
  • wp search replace - failed run means possible inclusion of platform domain urls in search engine results

Without checking the result, there's no early feedback mechanism that would informed customer that something went wrong during the deploy.

On Fri, 15 May 2020, 03:56 Fatima Sarah Khalid, [email protected] wrote:

Hi @marfillaster https://github.com/marfillaster thank you for opening this issue! I'm sorry, I'm not sure I understand the issue here - could you walk me through the false positive error that occurs?

My understanding of the passthru command was that we don't need to worry about the return value because we're just outputting to the browser.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pantheon-systems/quicksilver-examples/issues/169#issuecomment-628855115, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA5XQL7LZDZ63JBCXEBOFDRRREHFANCNFSM4M2LGKPQ .

marfillaster avatar May 14 '20 20:05 marfillaster

Oh I see, thank you for the explanation and the examples - that's very helpful.

I'm going to go ahead and see if I can test your recommended solution with some of these examples and then we can open a PR to get these usages updated.

cc @populist who's been working on maintaining this repo with me in case you have thoughts on the passthru command updates - I'm digging into this for the first time :)

sugaroverflow avatar May 14 '20 20:05 sugaroverflow

I definitely like the idea of providing examples that provide better error handling to folks who use them. Did a quick test of the passthru() method with our config_import script and can see errors surfaced in the output:

Fatal error: Command "drush config-import-error -y" exit status: 1 in /srv/bindings/c79d510f61594387817f1360626c86dd/code/private/scripts/drush_config_import/drush_config_import.php on line 7

populist avatar May 27 '20 16:05 populist

Thank you for looking into this and testing @populist!

I've been reading up on pass_thru() and wondering if it's being used incorrectly for these examples. Documentation indicates that pass_thru() is recommended for executing commands in which the returned output is something binary.

If we're having issues catching non-zero/non-binary exit codes, perhaps we shouldn't be using pass_thur() to begin with. If so, adding an error catch statement feels like treating the symptom, not the cause.

Instead, I'd like to replace the command with something else that supports nonzero output instead of adding a layer to the existing code - maybe with the system( ) command

Let me know what you think :)

sugaroverflow avatar Jun 09 '20 21:06 sugaroverflow

passthru takes an optional second parameter to capture the status result code (0-255).

The Terminus Build Tools plugin defines a convenience wrapper for passthru:

    /**
     * Call passthru; throw an exception on failure.
     *
     * @param string $command
     */
    protected function passthru($command)
    {
        $result = 0;
        $this->log()->notice("Running {cmd}", ['cmd' => $command]);
        passthru($command, $result);

        if ($result != 0) {
            throw new TerminusException('Command `{command}` failed with exit code {status}', ['command' => $loggedCommand, 'status' => $result]);
        }
    }

I simplified it slightly for comprehensibility. We could provide some utility traits in the examples so that users who copy them verbatim would get correct behavior. It would be desirable if the examples were correct, even though it is not entirely clear whether they were intended to ever be anything more than starting points for development.

greg-1-anderson avatar Jun 10 '20 01:06 greg-1-anderson

I received an update from Ken that the 500 timeout error is actually a client error and that engineering is looking into it.

Thanks for the example @greg-1-anderson - I like the idea of the convenience wrapper or a utility trait that expands on passthru() and allows us to catch errors - but how do we ship that with the examples? Duplicating this in every example feels redundant. @populist and I have been looking into maintaining this repo and making it easier to use so this feels relevant.

sugaroverflow avatar Jun 10 '20 18:06 sugaroverflow

I think that a good example:

  • Is clear
  • Is correct
  • Has no dependencies (works standalone)

I therefore think that duplicating a short passthru utility in every example is fine.

greg-1-anderson avatar Jun 10 '20 18:06 greg-1-anderson

If we start having a large number of helper functions / classes in each example, though, then the "is clear" part starts to become degraded. If this happens, then we should consider the best way to introduce dependencies to reduce duplication.

greg-1-anderson avatar Jun 10 '20 18:06 greg-1-anderson