From 737e7c85412ccf75ea1461398a91fea490cd026c Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 8 Sep 2020 12:15:34 -0700 Subject: [PATCH] When an in-process worker subtask fails permanently, don't fatal the whole process Summary: Ref T13552. Fixes T13569. Currently, if a process uses in-process tasks (usually, a debugging/diagnostic workflow) and those tasks (or tasks those tasks queue) fail permanently, the exception escapes to top level and the process exits. This isn't desirable; catch the exception and fail them locally instead. Test Plan: With a failing Asana integration and misconfigured Webhook, ran `bin/repository reparse --publish ...`. - Before: fatals on each substep. - After: warnings emitted for failed substep, but process completes. Maniphest Tasks: T13569, T13552 Differential Revision: https://secure.phabricator.com/D21459 --- .../daemon/workers/PhabricatorWorker.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/infrastructure/daemon/workers/PhabricatorWorker.php b/src/infrastructure/daemon/workers/PhabricatorWorker.php index f055544b7b..95e91cf7d5 100644 --- a/src/infrastructure/daemon/workers/PhabricatorWorker.php +++ b/src/infrastructure/daemon/workers/PhabricatorWorker.php @@ -162,6 +162,19 @@ abstract class PhabricatorWorker extends Phobject { try { $worker->executeTask(); $worker->flushTaskQueue(); + + $task_result = PhabricatorWorkerArchiveTask::RESULT_SUCCESS; + break; + } catch (PhabricatorWorkerPermanentFailureException $ex) { + $proxy = new PhutilProxyException( + pht( + 'In-process task ("%s") failed permanently.', + $task_class), + $ex); + + phlog($proxy); + + $task_result = PhabricatorWorkerArchiveTask::RESULT_FAILURE; break; } catch (PhabricatorWorkerYieldException $ex) { phlog( @@ -177,9 +190,7 @@ abstract class PhabricatorWorker extends Phobject { // object with a valid ID. $task->openTransaction(); $task->save(); - $archived = $task->archiveTask( - PhabricatorWorkerArchiveTask::RESULT_SUCCESS, - 0); + $archived = $task->archiveTask($task_result, 0); $task->saveTransaction(); return $archived;