Currently, the "Land Revision" repository operation shows a generic error if the push fails.
We should capture the error text so that users can react to messages emitted by commit hooks.
Currently, the "Land Revision" repository operation shows a generic error if the push fails.
We should capture the error text so that users can react to messages emitted by commit hooks.
To fix this:
First, here's the actual command we want to capture errors from, near line 125 of DrydockLandRepositoryOperation.php:
$interface->execx( 'git push origin -- %s:%s', 'HEAD', $push_dst);
Currently, if that fails it just throws an exception, and we get a generic error at top level ("Operation encountered an error.").
There's already a mechanism for raising errors and showing them nicely in the UI, which you can find an example of in DrydockWorkingCopyBlueprintImplementation.php near line 448:
try { $interface->execx('%C', $real_command); } catch (CommandException $ex) { $this->setWorkingCopyVCSErrorFromCommandException( $lease, self::PHASE_SQUASHMERGE, $show_command, $ex); throw $ex; }
So we just need to do something similar at the git push callsite.
The problem is that setWorkingCopyVCSErrorFromCommandException() is a protected method on DrydockWorkingCopyBlueprintImplementation, and DrydockRepositoryOperationType can't call it. We also don't have a $lease to pass.
However, we don't actually need this stuff. This is what happens with the merge error:
The copy step happens in DrydockRepositoryOperationUpdateWorker.php, near line 141:
$vcs_error = $working_copy->getWorkingCopyVCSError($lease); if ($vcs_error) { $operation ->setWorkingCopyVCSError($vcs_error) ->save(); }
So we can just write the error directly to the RepositoryOperation and skip the lease. I think something like this would work:
+ try { $interface->execx( 'git push origin -- %s:%s', 'HEAD', $push_dst); + } catch (CommandException $ex) { + $this->setWorkingCopyVCSError(...); + throw $ex; + }
The ... should be a dictionary like the one built in DrydockWorkingCopyBlueprintImplementation->setWorkingCopyVCSErrorFromCommandException(). It would be good to not duplicate that code. There are also sort of muddled responsibilities here where both WorkingCopyBlueprint and RepositoryOperation are somewhat responsible for handling VCS errors.
I think maybe we should just move this code to a separate class, since neither the Blueprint nor the RepositoryOperation really own it. So the implementation might look something like this:
Hopefully that roughly makes sense? This is a little tricky because it's a small change but affects a lot of different pieces.
+ $this->setWorkingCopyVCSError(...);
Oh, this is probably actually $operation->setWorkingCopyVCSError(...);
It looks like "git push" in DrydockLandRepositoryOperation.php doesn't get executed.
I put some var_dump as the following, and click "Land Revision", but no related log printed out.
+ try {
+ $interface->execx(
+ 'git push origin -- %s:%s',
+ 'HEAD',
+ $push_dst);
+ var_dump("++++++++++++++++");
+ } catch (CommandException $ex) {
+ var_dump("--------------");
+ var_dump($ex->getStdout());
+ var_dump($ex->$ex->getStderr());
+ var_dump("--------------");
Is there anything I missed here?
I think var_dump() will normally be hard to observe, since it will go to stdout but that isn't connected to anything by default so it will just vanish (we don't write stdout to the daemon log). My guess is that the code is running, you just aren't seeing the var_dump() output.
A couple of ways you can see the output are:
It would be nice to write a bin/differential land Dxxx to make testing easier, but I think it's a bit complex. We have a PhabricatorWorker::setRunAllTasksInProcess(true); mode to force tasks to run in the foreground, but right now it doesn't properly handle tasks that yield, and the Drydock tasks yield.
So far, I've been able to use a mixture of phlog() and bin/worker execute to debug this stuff without too much of an issue, but it's definitely a bit of a pain. Getting yields to work in the foreground is just also a bit of a pain.
When I put var_dump() in other parts of the code, I can see the output from /var/log/apache/error.log, but just can't see any output for the ones I mentioned above.
Any way, let me try the ways you suggested.