public function handleException(Exception $ex) { // Always log the unhandled exception. phlog($ex); $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); if (PhabricatorEnv::getEnvConfig('phabricator.show-stack-traces')) { $trace = $this->renderStackTrace($ex->getTrace()); } else { $trace = null; } $content = '<div class="aphront-unhandled-exception">' . '<div class="exception-message">' . $message . '</div>' . $trace . '</div>'; $user = $this->getRequest()->getUser(); if (!$user) { // If we hit an exception very early, we won't have a user. $user = new PhabricatorUser(); } $dialog = new AphrontDialogView(); $dialog->setTitle('Unhandled Exception ("' . $class . '")')->setClass('aphront-exception-dialog')->setUser($user)->appendChild($content); if ($this->getRequest()->isAjax()) { $dialog->addCancelButton('/', 'Close'); } $response = new AphrontDialogResponse(); $response->setDialog($dialog); return $response; }
public function processRequest() { // No CSRF for SendGrid. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $request = $this->getRequest(); $user = $request->getUser(); $raw_headers = $request->getStr('headers'); $raw_headers = explode("\n", rtrim($raw_headers)); $raw_dict = array(); foreach (array_filter($raw_headers) as $header) { list($name, $value) = explode(':', $header, 2); $raw_dict[$name] = ltrim($value); } $headers = array('to' => $request->getStr('to'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict; $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders($headers); $received->setBodies(array('text' => $request->getStr('text'), 'html' => $request->getStr('from'))); $file_phids = array(); foreach ($_FILES as $file_raw) { try { $file = PhabricatorFile::newFromPHPUpload($file_raw, array('authorPHID' => $user->getPHID())); $file_phids[] = $file->getPHID(); } catch (Exception $ex) { phlog($ex); } } $received->setAttachments($file_phids); $received->save(); $received->processReceivedMail(); $response = new AphrontWebpageResponse(); $response->setContent("Got it! Thanks, SendGrid!\n"); return $response; }
protected function doWork() { $lock = $this->acquireTaskLock(); $task = $this->loadTask(); $status = $task->getStatus(); switch ($task->getStatus()) { case PhabricatorWorkerBulkTask::STATUS_WAITING: // This is what we expect. break; default: throw new PhabricatorWorkerPermanentFailureException(pht('Found unexpected task status ("%s").', $status)); } $task->setStatus(PhabricatorWorkerBulkTask::STATUS_RUNNING)->save(); $lock->unlock(); $job = $this->loadJob(); $actor = $this->loadActor($job); try { $job->runTask($actor, $task); $status = PhabricatorWorkerBulkTask::STATUS_DONE; } catch (Exception $ex) { phlog($ex); $status = PhabricatorWorkerBulkTask::STATUS_FAIL; } $task->setStatus($status)->save(); $this->updateJob($job); }
private function assertParserResult(array $expect, $input, $file) { list($x, $y) = PhutilSocketChannel::newChannelPair(); $xp = new DiffusionMercurialWireClientSSHProtocolChannel($x); $y->write($input); $y->flush(); $y->closeWriteChannel(); $messages = array(); for ($ii = 0; $ii < count($expect); $ii++) { try { $messages[] = $xp->waitForMessage(); } catch (Exception $ex) { // This is probably the parser not producing as many messages as // we expect. Log the exception, but continue to the assertion below // since that will often be easier to diagnose. phlog($ex); break; } } $this->assertEqual($expect, $messages, $file); // Now, make sure the channel doesn't have *more* messages than we expect. // Specifically, it should throw when we try to read another message. $caught = null; try { $xp->waitForMessage(); } catch (Exception $ex) { $caught = $ex; } $this->assertTrue($caught instanceof Exception, pht("No extra messages for '%s'.", $file)); }
public function getKeys(array $keys) { $results = array(); if ($keys) { $map = $this->digestKeys($keys); $rows = queryfx_all($this->establishConnection('r'), 'SELECT * FROM %T WHERE cacheKeyHash IN (%Ls)', $this->getTableName(), $map); $rows = ipull($rows, null, 'cacheKey'); foreach ($keys as $key) { if (empty($rows[$key])) { continue; } $row = $rows[$key]; if ($row['cacheExpires'] && $row['cacheExpires'] < time()) { continue; } try { $results[$key] = $this->didReadValue($row['cacheFormat'], $row['cacheData']); } catch (Exception $ex) { // Treat this as a cache miss. phlog($ex); } } } return $results; }
public function addRemarkupSection($header, $text) { try { $engine = PhabricatorMarkupEngine::newMarkupEngine(array()); $engine->setConfig('viewer', $this->getViewer()); $engine->setMode(PhutilRemarkupEngine::MODE_TEXT); $styled_text = $engine->markupText($text); $this->addPlaintextSection($header, $styled_text); } catch (Exception $ex) { phlog($ex); $this->addTextSection($header, $text); } try { $mail_engine = PhabricatorMarkupEngine::newMarkupEngine(array()); $mail_engine->setConfig('viewer', $this->getViewer()); $mail_engine->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL); $mail_engine->setConfig('uri.base', PhabricatorEnv::getProductionURI('/')); $html = $mail_engine->markupText($text); $this->addHTMLSection($header, $html); } catch (Exception $ex) { phlog($ex); $this->addHTMLSection($header, $text); } return $this; }
public function destroyObject(PhabricatorDestructionEngine $engine, $object) { $src_phid = $object->getPHID(); try { $edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($src_phid))->execute(); } catch (Exception $ex) { // This is (presumably) a "no edges for this PHID type" exception. return; } $editor = new PhabricatorEdgeEditor(); foreach ($edges as $type => $type_edges) { foreach ($type_edges as $src => $src_edges) { foreach ($src_edges as $dst => $edge) { try { $editor->removeEdge($edge['src'], $edge['type'], $edge['dst']); } catch (Exception $ex) { // We can run into an exception while removing the edge if the // edge type no longer exists. This prevents us from figuring out // if there's an inverse type. Just ignore any errors here and // continue, since the best we can do is clean up all the edges // we still have information about. See T11201. phlog($ex); } } } } $editor->save(); }
public function handleRequest(AphrontRequest $request) { // No CSRF for Mailgun. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); if (!$this->verifyMessage()) { throw new Exception(pht('Mail signature is not valid. Check your Mailgun API key.')); } $user = $request->getUser(); $raw_headers = $request->getStr('headers'); $raw_headers = explode("\n", rtrim($raw_headers)); $raw_dict = array(); foreach (array_filter($raw_headers) as $header) { list($name, $value) = explode(':', $header, 2); $raw_dict[$name] = ltrim($value); } $headers = array('to' => $request->getStr('recipient'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict; $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders($headers); $received->setBodies(array('text' => $request->getStr('stripped-text'), 'html' => $request->getStr('stripped-html'))); $file_phids = array(); foreach ($_FILES as $file_raw) { try { $file = PhabricatorFile::newFromPHPUpload($file_raw, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $file_phids[] = $file->getPHID(); } catch (Exception $ex) { phlog($ex); } } $received->setAttachments($file_phids); $received->save(); $received->processReceivedMail(); $response = new AphrontWebpageResponse(); $response->setContent(pht("Got it! Thanks, Mailgun!\n")); return $response; }
public function handleRequestException(AphrontRequest $request, Exception $ex) { $viewer = $this->getViewer($request); // Some types of uninteresting request exceptions don't get logged, usually // because they are caused by the background radiation of bot traffic on // the internet. These include requests with bad CSRF tokens and // questionable "Host" headers. $should_log = true; if ($ex instanceof AphrontMalformedRequestException) { $should_log = !$ex->getIsUnlogged(); } if ($should_log) { phlog($ex); } $class = get_class($ex); $message = $ex->getMessage(); if ($ex instanceof AphrontSchemaQueryException) { $message .= "\n\n" . pht("NOTE: This usually indicates that the MySQL schema has not been " . "properly upgraded. Run '%s' to ensure your schema is up to date.", 'bin/storage upgrade'); } if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) { $trace = id(new AphrontStackTraceView())->setUser($viewer)->setTrace($ex->getTrace()); } else { $trace = null; } $content = phutil_tag('div', array('class' => 'aphront-unhandled-exception'), array(phutil_tag('div', array('class' => 'exception-message'), $message), $trace)); $dialog = new AphrontDialogView(); $dialog->setTitle(pht('Unhandled Exception ("%s")', $class))->setClass('aphront-exception-dialog')->setUser($viewer)->appendChild($content); if ($request->isAjax()) { $dialog->addCancelButton('/', pht('Close')); } return id(new AphrontDialogResponse())->setDialog($dialog)->setHTTPResponseCode(500); }
public function setKeys(array $keys, $ttl = null) { $this->validateKeys(array_keys($keys)); $this->lockCache(15); if ($ttl) { $ttl_epoch = time() + $ttl; } else { $ttl_epoch = null; } foreach ($keys as $key => $value) { $dict = array('value' => $value); if ($ttl_epoch) { $dict['ttl'] = $ttl_epoch; } try { $key_file = $this->getKeyFile($key); $key_dir = dirname($key_file); if (!Filesystem::pathExists($key_dir)) { Filesystem::createDirectory($key_dir, $mask = 0755, $recursive = true); } $new_file = $key_file . '.new'; Filesystem::writeFile($new_file, serialize($dict)); Filesystem::rename($new_file, $key_file); } catch (FilesystemException $ex) { phlog($ex); } } $this->unlockCache(); return $this; }
private function establishConnection() { $host = $this->getConfiguration('host'); $database = $this->getConfiguration('database'); $profiler = PhutilServiceProfiler::getInstance(); $call_id = $profiler->beginServiceCall(array('type' => 'connect', 'host' => $host, 'database' => $database)); $retries = max(1, $this->getConfiguration('retries', 3)); while ($retries--) { try { $conn = $this->connect(); $profiler->endServiceCall($call_id, array()); break; } catch (AphrontQueryException $ex) { if ($retries && $ex->getCode() == 2003) { $class = get_class($ex); $message = $ex->getMessage(); phlog(pht('Retrying (%d) after %s: %s', $retries, $class, $message)); } else { $profiler->endServiceCall($call_id, array()); throw $ex; } } } $this->connection = $conn; }
public function indexDocumentByPHID($phid) { try { $document = $this->buildAbstractDocumentByPHID($phid); $object = $this->loadDocumentByPHID($phid); // Automatically rebuild CustomField indexes if the object uses custom // fields. if ($object instanceof PhabricatorCustomFieldInterface) { $this->indexCustomFields($document, $object); } // Automatically rebuild subscriber indexes if the object is subscribable. if ($object instanceof PhabricatorSubscribableInterface) { $this->indexSubscribers($document); } $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine(); try { $engine->reindexAbstractDocument($document); } catch (Exception $ex) { $phid = $document->getPHID(); $class = get_class($engine); phlog("Unable to index document {$phid} with engine {$class}."); phlog($ex); } $this->dispatchDidUpdateIndexEvent($phid, $document); } catch (Exception $ex) { $class = get_class($this); phlog("Unable to build document {$phid} with indexer {$class}."); phlog($ex); } return $this; }
public function addRemarkupSection($text) { try { $engine = PhabricatorMarkupEngine::newMarkupEngine(array()); $engine->setConfig('viewer', $this->getViewer()); $engine->setMode(PhutilRemarkupEngine::MODE_TEXT); $styled_text = $engine->markupText($text); $this->sections[] = $styled_text; } catch (Exception $ex) { phlog($ex); $this->sections[] = $text; } try { $mail_engine = PhabricatorMarkupEngine::newMarkupEngine(array()); $mail_engine->setConfig('viewer', $this->getViewer()); $mail_engine->setMode(PhutilRemarkupEngine::MODE_HTML_MAIL); $mail_engine->setConfig('uri.base', PhabricatorEnv::getProductionURI('/')); $html = $mail_engine->markupText($text); $this->htmlSections[] = $html; } catch (Exception $ex) { phlog($ex); $this->htmlSections[] = phutil_escape_html_newlines(phutil_tag('div', array(), $text)); } return $this; }
protected function execute(ConduitAPIRequest $request) { $results = array(); $user = $request->getUser(); $view_type = $request->getValue('view'); if (!$view_type) { $view_type = 'data'; } $limit = $request->getValue('limit'); if (!$limit) { $limit = $this->getDefaultLimit(); } $filter_phids = $request->getValue('filterPHIDs'); if (!$filter_phids) { $filter_phids = array(); } $query = id(new PhabricatorFeedQuery())->setLimit($limit)->setFilterPHIDs($filter_phids)->setViewer($user); $after = $request->getValue('after'); if (strlen($after)) { $query->setAfterID($after); } $before = $request->getValue('before'); if (strlen($before)) { $query->setBeforeID($before); } $stories = $query->execute(); if ($stories) { foreach ($stories as $story) { $story_data = $story->getStoryData(); $data = null; try { $view = $story->renderView(); } catch (Exception $ex) { // When stories fail to render, just fail that story. phlog($ex); continue; } $view->setEpoch($story->getEpoch()); $view->setUser($user); switch ($view_type) { case 'html': $data = $view->render(); break; case 'html-summary': $data = $view->render(); break; case 'data': $data = array('class' => $story_data->getStoryType(), 'epoch' => $story_data->getEpoch(), 'authorPHID' => $story_data->getAuthorPHID(), 'chronologicalKey' => $story_data->getChronologicalKey(), 'data' => $story_data->getStoryData()); break; case 'text': $data = array('class' => $story_data->getStoryType(), 'epoch' => $story_data->getEpoch(), 'authorPHID' => $story_data->getAuthorPHID(), 'chronologicalKey' => $story_data->getChronologicalKey(), 'objectPHID' => $story->getPrimaryObjectPHID(), 'text' => $story->renderText()); break; default: throw new ConduitException('ERR-UNKNOWN-TYPE'); } $results[$story_data->getPHID()] = $data; } } return $results; }
public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $iterator = $this->buildIterator($args); if (!$iterator) { throw new PhutilArgumentUsageException(pht('Either specify a list of files to compact, or use `--all` ' . 'to compact all files.')); } $is_dry_run = $args->getArg('dry-run'); foreach ($iterator as $file) { $monogram = $file->getMonogram(); $hash = $file->getContentHash(); if (!$hash) { $console->writeOut("%s\n", pht('%s: No content hash.', $monogram)); continue; } // Find other files with the same content hash. We're going to point // them at the data for this file. $similar_files = id(new PhabricatorFile())->loadAllWhere('contentHash = %s AND id != %d AND (storageEngine != %s OR storageHandle != %s)', $hash, $file->getID(), $file->getStorageEngine(), $file->getStorageHandle()); if (!$similar_files) { $console->writeOut("%s\n", pht('%s: No other files with the same content hash.', $monogram)); continue; } // Only compact files into this one if we can load the data. This // prevents us from breaking working files if we're missing some data. try { $data = $file->loadFileData(); } catch (Exception $ex) { $data = null; } if ($data === null) { $console->writeOut("%s\n", pht('%s: Unable to load file data; declining to compact.', $monogram)); continue; } foreach ($similar_files as $similar_file) { if ($is_dry_run) { $console->writeOut("%s\n", pht('%s: Would compact storage with %s.', $monogram, $similar_file->getMonogram())); continue; } $console->writeOut("%s\n", pht('%s: Compacting storage with %s.', $monogram, $similar_file->getMonogram())); $old_instance = null; try { $old_instance = $similar_file->instantiateStorageEngine(); $old_engine = $similar_file->getStorageEngine(); $old_handle = $similar_file->getStorageHandle(); } catch (Exception $ex) { // If the old stuff is busted, we just won't try to delete the // old data. phlog($ex); } $similar_file->setStorageEngine($file->getStorageEngine())->setStorageHandle($file->getStorageHandle())->save(); if ($old_instance) { $similar_file->deleteFileDataIfUnused($old_instance, $old_engine, $old_handle); } } } return 0; }
protected function doWork() { $target = $this->loadBuildTarget(); $build = $target->getBuild(); $viewer = $this->getViewer(); $target->setDateStarted(time()); try { if ($target->getBuildGeneration() !== $build->getBuildGeneration()) { throw new HarbormasterBuildAbortedException(); } $status_pending = HarbormasterBuildTarget::STATUS_PENDING; if ($target->getTargetStatus() == $status_pending) { $target->setTargetStatus(HarbormasterBuildTarget::STATUS_BUILDING); $target->save(); } $implementation = $target->getImplementation(); $implementation->setCurrentWorkerTaskID($this->getCurrentWorkerTaskID()); $implementation->execute($build, $target); $next_status = HarbormasterBuildTarget::STATUS_PASSED; if ($implementation->shouldWaitForMessage($target)) { $next_status = HarbormasterBuildTarget::STATUS_WAITING; } $target->setTargetStatus($next_status); if ($target->isComplete()) { $target->setDateCompleted(PhabricatorTime::getNow()); } $target->save(); } catch (PhabricatorWorkerYieldException $ex) { // If the target wants to yield, let that escape without further // processing. We'll resume after the task retries. throw $ex; } catch (HarbormasterBuildFailureException $ex) { // A build step wants to fail explicitly. $target->setTargetStatus(HarbormasterBuildTarget::STATUS_FAILED); $target->setDateCompleted(PhabricatorTime::getNow()); $target->save(); } catch (HarbormasterBuildAbortedException $ex) { // A build step is aborting because the build has been restarted. $target->setTargetStatus(HarbormasterBuildTarget::STATUS_ABORTED); $target->setDateCompleted(PhabricatorTime::getNow()); $target->save(); } catch (Exception $ex) { phlog($ex); try { $log = $build->createLog($target, 'core', 'exception'); $start = $log->start(); $log->append((string) $ex); $log->finalize($start); } catch (Exception $log_ex) { phlog($log_ex); } $target->setTargetStatus(HarbormasterBuildTarget::STATUS_FAILED); $target->setDateCompleted(time()); $target->save(); } id(new HarbormasterBuildEngine())->setViewer($viewer)->setBuild($build)->continueBuild(); }
public function handleRequestException(AphrontRequest $request, Exception $ex) { // Log these; they don't get shown on the client and can be difficult // to debug. phlog($ex); $response = new AphrontAjaxResponse(); $response->setError(array('code' => get_class($ex), 'info' => $ex->getMessage())); return $response; }
public function receiveMessage(PhabricatorBotMessage $message) { switch ($message->getCommand()) { case 'MESSAGE': $matches = null; $text = $message->getBody(); $target_name = $message->getTarget()->getName(); if (empty($this->recentlyMentioned[$target_name])) { $this->recentlyMentioned[$target_name] = array(); } $pattern = '@^' . '(?:' . $this->getConfig('nick', 'phabot') . ')?' . '.?\\s*tell me about ' . '(.*)' . '$@'; if (preg_match($pattern, $text, $matches)) { $slug = $matches[1]; $quiet_until = idx($this->recentlyMentioned[$target_name], $slug, 0) + 60 * 10; if (time() < $quiet_until) { // Remain quiet on this channel. break; } else { $this->recentlyMentioned[$target_name][$slug] = time(); } try { $result = $this->getConduit()->callMethodSynchronous('phriction.info', array('slug' => 'docbot/docs/' . $slug)); } catch (ConduitClientException $ex) { phlog($ex); $result = null; } $response = array(); if ($result) { $content = phutil_split_lines($result['content'], $retain_newlines = false); foreach ($content as $line) { $response = array_merge($response, str_split($line, 400)); if (count($response) >= 3) { break; } } } else { $response[] = "Nothing to say about " . $slug; } foreach (array_slice($response, 0, 3) as $output) { $this->replyTo($message, html_entity_decode($output)); } break; } $pattern = '@' . $this->getConfig('nick', 'phabot') . ' remember ' . '(.*?)' . ' as:' . '(.*)$' . '@'; if (preg_match($pattern, $text, $matches)) { $result = $this->getConduit()->callMethodSynchronous('phriction.edit', array('slug' => 'docbot/docs/' . $matches[1], 'content' => $matches[2])); $slug = explode('/', trim($result['slug'], '/'), 3); $output = "Saved as '{$slug[2]}' at {$result['uri']}"; $this->replyTo($message, $output); unset($this->recentlyMentioned[$target_name][$slug[2]]); unset($this->recentlyMentioned[$target_name][$matches[1]]); break; } break; } }
private function mirrorRepository(PhabricatorRepository $repository) { try { id(new PhabricatorRepositoryMirrorEngine())->setRepository($repository)->pushToMirrors(); } catch (Exception $ex) { // TODO: We should report these into the UI properly, but for now just // complain. These errors are much less severe than pull errors. $proxy = new PhutilProxyException(pht('Error while pushing "%s" repository to mirrors.', $repository->getMonogram()), $ex); phlog($proxy); } }
protected static final function reindexAbstractDocument(PhabricatorSearchAbstractDocument $document) { $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine(); try { $engine->reindexAbstractDocument($document); } catch (Exception $ex) { $phid = $document->getPHID(); $class = get_class($engine); phlog("Unable to index document {$phid} by engine {$class}."); } }
/** * Publishes stories into JIRA using the JIRA API. */ protected function publishFeedStory() { $story = $this->getFeedStory(); $viewer = $this->getViewer(); $provider = $this->getProvider(); $object = $this->getStoryObject(); $publisher = $this->getPublisher(); $jira_issue_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorJiraIssueHasObjectEdgeType::EDGECONST); if (!$jira_issue_phids) { $this->log("%s\n", pht('Story is about an object with no linked JIRA issues.')); return; } $do_anything = $this->shouldPostComment() || $this->shouldPostLink(); if (!$do_anything) { $this->log("%s\n", pht('JIRA integration is configured not to post anything.')); return; } $xobjs = id(new DoorkeeperExternalObjectQuery())->setViewer($viewer)->withPHIDs($jira_issue_phids)->execute(); if (!$xobjs) { $this->log("%s\n", pht('Story object has no corresponding external JIRA objects.')); return; } $try_users = $this->findUsersToPossess(); if (!$try_users) { $this->log("%s\n", pht('No users to act on linked JIRA objects.')); return; } $xobjs = mgroup($xobjs, 'getApplicationDomain'); foreach ($xobjs as $domain => $xobj_list) { $accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs($try_users)->withAccountTypes(array($provider->getProviderType()))->withAccountDomains(array($domain))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute(); // Reorder accounts in the original order. // TODO: This needs to be adjusted if/when we allow you to link multiple // accounts. $accounts = mpull($accounts, null, 'getUserPHID'); $accounts = array_select_keys($accounts, $try_users); foreach ($xobj_list as $xobj) { foreach ($accounts as $account) { try { $jira_key = $xobj->getObjectID(); if ($this->shouldPostComment()) { $this->postComment($account, $jira_key); } if ($this->shouldPostLink()) { $this->postLink($account, $jira_key); } break; } catch (HTTPFutureResponseStatus $ex) { phlog($ex); $this->log("%s\n", pht('Failed to update object %s using user %s.', $xobj->getObjectID(), $account->getUserPHID())); } } } } }
public function pullRefs(array $refs) { $token = $this->getGitHubAccessToken(); if (!strlen($token)) { return null; } $template = id(new PhutilGitHubFuture())->setAccessToken($token); $futures = array(); $id_map = mpull($refs, 'getObjectID', 'getObjectKey'); foreach ($id_map as $key => $id) { list($user, $repository, $number) = $this->parseGitHubIssueID($id); $uri = "/repos/{$user}/{$repository}/issues/{$number}"; $data = array(); $futures[$key] = id(clone $template)->setRawGitHubQuery($uri, $data); } $results = array(); $failed = array(); foreach (new FutureIterator($futures) as $key => $future) { try { $results[$key] = $future->resolve(); } catch (Exception $ex) { if ($ex instanceof HTTPFutureResponseStatus && $ex->getStatusCode() == 404) { // TODO: Do we end up here for deleted objects and invisible // objects? } else { phlog($ex); $failed[$key] = $ex; } } } $viewer = $this->getViewer(); foreach ($refs as $ref) { $ref->setAttribute('name', pht('GitHub Issue %s', $ref->getObjectID())); $did_fail = idx($failed, $ref->getObjectKey()); if ($did_fail) { $ref->setSyncFailed(true); continue; } $result = idx($results, $ref->getObjectKey()); if (!$result) { continue; } $body = $result->getBody(); $ref->setIsVisible(true); $ref->setAttribute('api.raw', $body); $ref->setAttribute('name', $body['title']); $obj = $ref->getExternalObject(); $this->fillObjectFromData($obj, $result); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $obj->save(); unset($unguarded); } }
public static function tryToPostMessage(array $data) { if (!PhabricatorEnv::getEnvConfig('notification.enabled')) { return; } try { self::postMessage($data); } catch (Exception $ex) { // Just ignore any issues here. phlog($ex); } }
public function execute(PhutilArgumentParser $args) { $console = PhutilConsole::getConsole(); $is_all = $args->getArg('all'); $is_type = $args->getArg('type'); $is_force = $args->getArg('force'); $obj_names = $args->getArg('objects'); if ($obj_names && ($is_all || $is_type)) { throw new PhutilArgumentUsageException(pht("You can not name objects to index alongside the '%s' or '%s' flags.", '--all', '--type')); } else { if (!$obj_names && !($is_all || $is_type)) { throw new PhutilArgumentUsageException(pht("Provide one of '%s', '%s' or a list of object names.", '--all', '--type')); } } if ($obj_names) { $phids = $this->loadPHIDsByNames($obj_names); } else { $phids = $this->loadPHIDsByTypes($is_type); } if (!$phids) { throw new PhutilArgumentUsageException(pht('Nothing to index!')); } if ($args->getArg('background')) { $is_background = true; } else { PhabricatorWorker::setRunAllTasksInProcess(true); $is_background = false; } if (!$is_background) { $console->writeOut("%s\n", pht('Run this workflow with "%s" to queue tasks for the daemon workers.', '--background')); } $groups = phid_group_by_type($phids); foreach ($groups as $group_type => $group) { $console->writeOut("%s\n", pht('Indexing %d object(s) of type %s.', count($group), $group_type)); } $bar = id(new PhutilConsoleProgressBar())->setTotal(count($phids)); $parameters = array('force' => $is_force); $any_success = false; foreach ($phids as $phid) { try { PhabricatorSearchWorker::queueDocumentForIndexing($phid, $parameters); $any_success = true; } catch (Exception $ex) { phlog($ex); } $bar->update(1); } $bar->done(); if (!$any_success) { throw new Exception(pht('Failed to rebuild search index for any documents.')); } }
public function runBackgroundTasks() { foreach ($this->futures as $key => $future) { try { if ($future->isReady()) { unset($this->futures[$key]); } } catch (Exception $ex) { unset($this->futures[$key]); phlog($ex); } } }
protected function execute(ConduitAPIRequest $request) { $diff_id = $request->getValue('diff_id'); if (!$diff_id) { throw new ConduitException('ERR_BAD_DIFF'); } $file = $request->getValue('file'); $name = $request->getValue('name'); $message = $request->getValue('message'); $result = $request->getValue('result'); $diff_property = id(new DifferentialDiffProperty())->loadOneWhere('diffID = %d AND name = %s', $diff_id, 'arc:unit'); if (!$diff_property) { throw new ConduitException('ERR_NO_RESULTS'); } $diff = id(new DifferentialDiff())->load($diff_id); $unit_results = $diff_property->getData(); $postponed_count = 0; $unit_status = null; foreach ($unit_results as &$unit_result) { // Update the results for the test that has the same path. if (($unit_result['name'] === $file || $unit_result['name'] === $diff->getSourcePath() . $file) && $unit_result['result'] === DifferentialUnitTestResult::RESULT_POSTPONED) { $unit_result['name'] = $name; $unit_result['result'] = $result; $unit_result['userdata'] = $message; $unit_status = $result; break; } } unset($unit_result); if (!$unit_status) { phlog("Could not update test results: {$diff_id} {$file} {$name}" . " {$result} {$message}"); return; } $diff_property->setData($unit_results); $diff_property->save(); foreach ($unit_results as $unit_result) { if ($unit_result['result'] == DifferentialUnitTestResult::RESULT_POSTPONED) { $postponed_count++; } } $status_codes = array(DifferentialUnitTestResult::RESULT_PASS => DifferentialUnitStatus::UNIT_OKAY, DifferentialUnitTestResult::RESULT_UNSOUND => DifferentialUnitStatus::UNIT_WARN, DifferentialUnitTestResult::RESULT_FAIL => DifferentialUnitStatus::UNIT_FAIL, DifferentialUnitTestResult::RESULT_SKIP => DifferentialUnitStatus::UNIT_SKIP, DifferentialUnitTestResult::RESULT_POSTPONED => DifferentialUnitStatus::UNIT_POSTPONED); if ($diff->getUnitStatus() == DifferentialUnitStatus::UNIT_POSTPONED) { if ($postponed_count == 0 || $unit_status != DifferentialUnitTestResult::RESULT_PASS) { $diff->setUnitStatus(idx($status_codes, $unit_status, DifferentialUnitStatus::UNIT_NONE)); $diff->save(); } } return; }
public function handleRequest(AphrontRequest $request) { // No CSRF for Mailgun. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); if (!$this->verifyMessage()) { throw new Exception(pht('Mail signature is not valid. Check your Mailgun API key.')); } $raw_headers = $request->getStr('message-headers'); $raw_dict = array(); if (strlen($raw_headers)) { $raw_headers = phutil_json_decode($raw_headers); foreach ($raw_headers as $raw_header) { list($name, $value) = $raw_header; $raw_dict[$name] = $value; } } $headers = array('to' => $request->getStr('recipient'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict; $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders($headers); $received->setBodies(array('text' => $request->getStr('stripped-text'), 'html' => $request->getStr('stripped-html'))); $file_phids = array(); foreach ($_FILES as $file_raw) { try { $file = PhabricatorFile::newFromPHPUpload($file_raw, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $file_phids[] = $file->getPHID(); } catch (Exception $ex) { phlog($ex); } } $received->setAttachments($file_phids); try { $received->save(); $received->processReceivedMail(); } catch (Exception $ex) { // We can get exceptions here in two cases. // First, saving the message may throw if we have already received a // message with the same Message ID. In this case, we're declining to // process a duplicate message, so failing silently is correct. // Second, processing the message may throw (for example, if it contains // an invalid !command). This will generate an email as a side effect, // so we don't need to explicitly handle the exception here. // In these cases, we want to return HTTP 200. If we do not, MailGun will // re-transmit the message later. phlog($ex); } $response = new AphrontWebpageResponse(); $response->setContent(pht("Got it! Thanks, Mailgun!\n")); return $response; }
public function setException(Exception $exception) { // Log the exception unless it's specifically a silent malformed request // exception. $should_log = true; if ($exception instanceof AphrontMalformedRequestException) { if ($exception->getIsUnlogged()) { $should_log = false; } } if ($should_log) { phlog($exception); } $this->exception = $exception; return $this; }
/** * Publishes stories into JIRA using the JIRA API. */ protected function publishFeedStory() { $story = $this->getFeedStory(); $viewer = $this->getViewer(); $provider = $this->getProvider(); $object = $this->getStoryObject(); $publisher = $this->getPublisher(); $jira_issue_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($object->getPHID(), PhabricatorEdgeConfig::TYPE_PHOB_HAS_JIRAISSUE); if (!$jira_issue_phids) { $this->log("Story is about an object with no linked JIRA issues.\n"); return; } $xobjs = id(new DoorkeeperExternalObjectQuery())->setViewer($viewer)->withPHIDs($jira_issue_phids)->execute(); if (!$xobjs) { $this->log("Story object has no corresponding external JIRA objects.\n"); return; } $try_users = $this->findUsersToPossess(); if (!$try_users) { $this->log("No users to act on linked JIRA objects.\n"); return; } $story_text = $this->renderStoryText(); $xobjs = mgroup($xobjs, 'getApplicationDomain'); foreach ($xobjs as $domain => $xobj_list) { $accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs($try_users)->withAccountTypes(array($provider->getProviderType()))->withAccountDomains(array($domain))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute(); // Reorder accounts in the original order. // TODO: This needs to be adjusted if/when we allow you to link multiple // accounts. $accounts = mpull($accounts, null, 'getUserPHID'); $accounts = array_select_keys($accounts, $try_users); foreach ($xobj_list as $xobj) { foreach ($accounts as $account) { try { $provider->newJIRAFuture($account, 'rest/api/2/issue/' . $xobj->getObjectID() . '/comment', 'POST', array('body' => $story_text))->resolveJSON(); break; } catch (HTTPFutureResponseStatus $ex) { phlog($ex); $this->log("Failed to update object %s using user %s.\n", $xobj->getObjectID(), $account->getUserPHID()); } } } } }
public final function handleRequest(AphrontRequest $request) { $data = $request->getURIMap(); $project = $data['gerritProject']; if (!isset(self::$projects[$project])) { return new Aphront404Response(); } $CALLSIGN = self::$projects[$project]; if ($data['action'] == 'branch') { if (!isset($data['branch'])) { return new Aphront404Response(); } $branch = $data['branch']; // get rid of refs/heads prefix $branch = str_replace('refs/heads', '', $branch); $branch = trim($branch, '/'); $branch = str_replace('HEAD', '', $branch); // double encode any forward slashes in ref. $branch = str_replace('/', '%252F', $branch); if (strlen($branch) == 0) { return id(new AphrontRedirectResponse())->setURI("/diffusion/{$CALLSIGN}/browse/"); } else { return id(new AphrontRedirectResponse())->setURI("/diffusion/{$CALLSIGN}/browse/{$branch}/"); } } if ($data['action'] == 'browse') { if (!isset($data['branch']) || !isset($data['file'])) { return new Aphront404Response(); } $branch = $data['branch']; $file = $data['file']; return id(new AphrontRedirectResponse())->setURI("/diffusion/{$CALLSIGN}/browse/{$branch}/{$file}"); } if ($data['action'] == 'revision') { $sha = isset($data['sha']) ? $data['sha'] : $data['branch']; return id(new AphrontRedirectResponse())->setURI('/r' . $CALLSIGN . $sha); } if ($data['action'] == 'project') { return id(new AphrontRedirectResponse())->setURI("/diffusion/{$CALLSIGN}/"); } phlog('did not match any repository redirect action'); return new Aphront404Response(); }