mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Improve exception behavior for storage engine failures
Summary: See T1021. Raise configuration or implementation exceptions immediately. When all engines fail, raise an aggregate exception with details. Test Plan: Forced all engines to fail, received an aggregate exception. Forced an engine to fail with a config exception, recevied it immediately. Reviewers: btrahan, vrana, jungejason Reviewed By: btrahan CC: aran Maniphest Tasks: T1021 Differential Revision: https://secure.phabricator.com/D2157
This commit is contained in:
parent
06367c4801
commit
62e41040f0
11 changed files with 111 additions and 54 deletions
|
@ -397,7 +397,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-dialog-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/1c0a5f75/rsrc/css/aphront/dialog-view.css',
|
||||
'uri' => '/res/531ebee9/rsrc/css/aphront/dialog-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -760,7 +760,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' =>
|
||||
array(
|
||||
'uri' => '/res/43f964a7/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||
'uri' => '/res/76a52ae3/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2399,7 +2399,7 @@ celerity_register_resource_map(array(
|
|||
), array(
|
||||
'packages' =>
|
||||
array(
|
||||
'c7d9f973' =>
|
||||
'9ca700e9' =>
|
||||
array(
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
|
@ -2424,7 +2424,7 @@ celerity_register_resource_map(array(
|
|||
17 => 'aphront-pager-view-css',
|
||||
18 => 'phabricator-transaction-view-css',
|
||||
),
|
||||
'uri' => '/res/pkg/c7d9f973/core.pkg.css',
|
||||
'uri' => '/res/pkg/9ca700e9/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'21d01ed8' =>
|
||||
|
@ -2470,7 +2470,7 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/216b9542/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'a3cabbba' =>
|
||||
'f6a0c401' =>
|
||||
array(
|
||||
'name' => 'differential.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -2493,7 +2493,7 @@ celerity_register_resource_map(array(
|
|||
15 => 'javelin-behavior-differential-dropdown-menus',
|
||||
16 => 'javelin-behavior-buoyant',
|
||||
),
|
||||
'uri' => '/res/pkg/a3cabbba/differential.pkg.js',
|
||||
'uri' => '/res/pkg/f6a0c401/differential.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'4ccda8a6' =>
|
||||
|
@ -2570,20 +2570,20 @@ celerity_register_resource_map(array(
|
|||
'reverse' =>
|
||||
array(
|
||||
'aphront-attached-file-view-css' => '8db30c56',
|
||||
'aphront-crumbs-view-css' => 'c7d9f973',
|
||||
'aphront-dialog-view-css' => 'c7d9f973',
|
||||
'aphront-form-view-css' => 'c7d9f973',
|
||||
'aphront-crumbs-view-css' => '9ca700e9',
|
||||
'aphront-dialog-view-css' => '9ca700e9',
|
||||
'aphront-form-view-css' => '9ca700e9',
|
||||
'aphront-headsup-action-list-view-css' => '216b9542',
|
||||
'aphront-list-filter-view-css' => 'c7d9f973',
|
||||
'aphront-pager-view-css' => 'c7d9f973',
|
||||
'aphront-panel-view-css' => 'c7d9f973',
|
||||
'aphront-side-nav-view-css' => 'c7d9f973',
|
||||
'aphront-table-view-css' => 'c7d9f973',
|
||||
'aphront-tokenizer-control-css' => 'c7d9f973',
|
||||
'aphront-typeahead-control-css' => 'c7d9f973',
|
||||
'aphront-list-filter-view-css' => '9ca700e9',
|
||||
'aphront-pager-view-css' => '9ca700e9',
|
||||
'aphront-panel-view-css' => '9ca700e9',
|
||||
'aphront-side-nav-view-css' => '9ca700e9',
|
||||
'aphront-table-view-css' => '9ca700e9',
|
||||
'aphront-tokenizer-control-css' => '9ca700e9',
|
||||
'aphront-typeahead-control-css' => '9ca700e9',
|
||||
'differential-changeset-view-css' => '216b9542',
|
||||
'differential-core-view-css' => '216b9542',
|
||||
'differential-inline-comment-editor' => 'a3cabbba',
|
||||
'differential-inline-comment-editor' => 'f6a0c401',
|
||||
'differential-local-commits-view-css' => '216b9542',
|
||||
'differential-revision-add-comment-css' => '216b9542',
|
||||
'differential-revision-comment-css' => '216b9542',
|
||||
|
@ -2594,27 +2594,27 @@ celerity_register_resource_map(array(
|
|||
'diffusion-commit-view-css' => '4ccda8a6',
|
||||
'javelin-behavior' => '4fbae2af',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '2af849fb',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'a3cabbba',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'a3cabbba',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'f6a0c401',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'f6a0c401',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => '21d01ed8',
|
||||
'javelin-behavior-buoyant' => 'a3cabbba',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'a3cabbba',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => 'a3cabbba',
|
||||
'javelin-behavior-differential-comment-jump' => 'a3cabbba',
|
||||
'javelin-behavior-differential-diff-radios' => 'a3cabbba',
|
||||
'javelin-behavior-differential-dropdown-menus' => 'a3cabbba',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'a3cabbba',
|
||||
'javelin-behavior-differential-feedback-preview' => 'a3cabbba',
|
||||
'javelin-behavior-differential-keyboard-navigation' => 'a3cabbba',
|
||||
'javelin-behavior-differential-populate' => 'a3cabbba',
|
||||
'javelin-behavior-differential-show-more' => 'a3cabbba',
|
||||
'javelin-behavior-buoyant' => 'f6a0c401',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'f6a0c401',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => 'f6a0c401',
|
||||
'javelin-behavior-differential-comment-jump' => 'f6a0c401',
|
||||
'javelin-behavior-differential-diff-radios' => 'f6a0c401',
|
||||
'javelin-behavior-differential-dropdown-menus' => 'f6a0c401',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'f6a0c401',
|
||||
'javelin-behavior-differential-feedback-preview' => 'f6a0c401',
|
||||
'javelin-behavior-differential-keyboard-navigation' => 'f6a0c401',
|
||||
'javelin-behavior-differential-populate' => 'f6a0c401',
|
||||
'javelin-behavior-differential-show-more' => 'f6a0c401',
|
||||
'javelin-behavior-maniphest-batch-selector' => '86fc0b0c',
|
||||
'javelin-behavior-maniphest-transaction-controls' => '86fc0b0c',
|
||||
'javelin-behavior-maniphest-transaction-expand' => '86fc0b0c',
|
||||
'javelin-behavior-maniphest-transaction-preview' => '86fc0b0c',
|
||||
'javelin-behavior-phabricator-autofocus' => '21d01ed8',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => '21d01ed8',
|
||||
'javelin-behavior-phabricator-object-selector' => 'a3cabbba',
|
||||
'javelin-behavior-phabricator-object-selector' => 'f6a0c401',
|
||||
'javelin-behavior-phabricator-watch-anchor' => '21d01ed8',
|
||||
'javelin-behavior-refresh-csrf' => '21d01ed8',
|
||||
'javelin-behavior-workflow' => '21d01ed8',
|
||||
|
@ -2637,23 +2637,23 @@ celerity_register_resource_map(array(
|
|||
'javelin-workflow' => '21d01ed8',
|
||||
'maniphest-task-summary-css' => '8db30c56',
|
||||
'maniphest-transaction-detail-css' => '8db30c56',
|
||||
'phabricator-app-buttons-css' => 'c7d9f973',
|
||||
'phabricator-app-buttons-css' => '9ca700e9',
|
||||
'phabricator-content-source-view-css' => '216b9542',
|
||||
'phabricator-core-buttons-css' => 'c7d9f973',
|
||||
'phabricator-core-css' => 'c7d9f973',
|
||||
'phabricator-directory-css' => 'c7d9f973',
|
||||
'phabricator-drag-and-drop-file-upload' => 'a3cabbba',
|
||||
'phabricator-core-buttons-css' => '9ca700e9',
|
||||
'phabricator-core-css' => '9ca700e9',
|
||||
'phabricator-directory-css' => '9ca700e9',
|
||||
'phabricator-drag-and-drop-file-upload' => 'f6a0c401',
|
||||
'phabricator-dropdown-menu' => '21d01ed8',
|
||||
'phabricator-jump-nav' => 'c7d9f973',
|
||||
'phabricator-jump-nav' => '9ca700e9',
|
||||
'phabricator-keyboard-shortcut' => '21d01ed8',
|
||||
'phabricator-keyboard-shortcut-manager' => '21d01ed8',
|
||||
'phabricator-menu-item' => '21d01ed8',
|
||||
'phabricator-object-selector-css' => '216b9542',
|
||||
'phabricator-paste-file-upload' => '21d01ed8',
|
||||
'phabricator-remarkup-css' => 'c7d9f973',
|
||||
'phabricator-shaped-request' => 'a3cabbba',
|
||||
'phabricator-standard-page-view' => 'c7d9f973',
|
||||
'phabricator-transaction-view-css' => 'c7d9f973',
|
||||
'syntax-highlighting-css' => 'c7d9f973',
|
||||
'phabricator-remarkup-css' => '9ca700e9',
|
||||
'phabricator-shaped-request' => 'f6a0c401',
|
||||
'phabricator-standard-page-view' => '9ca700e9',
|
||||
'phabricator-transaction-view-css' => '9ca700e9',
|
||||
'syntax-highlighting-css' => '9ca700e9',
|
||||
),
|
||||
));
|
||||
|
|
|
@ -604,6 +604,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFileProxyImage' => 'applications/files/storage/proxyimage',
|
||||
'PhabricatorFileSideNavView' => 'applications/files/view/sidenav',
|
||||
'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob',
|
||||
'PhabricatorFileStorageConfigurationException' => 'applications/files/exception/configuration',
|
||||
'PhabricatorFileStorageEngine' => 'applications/files/engine/base',
|
||||
'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/base',
|
||||
'PhabricatorFileTransformController' => 'applications/files/controller/transform',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -109,7 +109,7 @@ final class PhabricatorLocalDiskFileStorageEngine
|
|||
$root = PhabricatorEnv::getEnvConfig('storage.local-disk.path');
|
||||
|
||||
if (!$root || $root == '/' || $root[0] != '/') {
|
||||
throw new Exception(
|
||||
throw new PhabricatorFileStorageConfigurationException(
|
||||
"Malformed local disk storage root. You must provide an absolute ".
|
||||
"path, and can not use '/' as the root.");
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/writeguard');
|
||||
phutil_require_module('phabricator', 'applications/files/engine/base');
|
||||
phutil_require_module('phabricator', 'applications/files/exception/configuration');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -96,7 +96,8 @@ final class PhabricatorS3FileStorageEngine
|
|||
private function getBucketName() {
|
||||
$bucket = PhabricatorEnv::getEnvConfig('storage.s3.bucket');
|
||||
if (!$bucket) {
|
||||
throw new Exception("No 'storage.s3.bucket' specified!");
|
||||
throw new PhabricatorFileStorageConfigurationException(
|
||||
"No 'storage.s3.bucket' specified!");
|
||||
}
|
||||
return $bucket;
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ final class PhabricatorS3FileStorageEngine
|
|||
$secret_key = PhabricatorEnv::getEnvConfig('amazon-s3.secret-key');
|
||||
|
||||
if (!$access_key || !$secret_key) {
|
||||
throw new Exception(
|
||||
throw new PhabricatorFileStorageConfigurationException(
|
||||
"Specify 'amazon-s3.access-key' and 'amazon-s3.secret-key'!");
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/writeguard');
|
||||
phutil_require_module('phabricator', 'applications/files/engine/base');
|
||||
phutil_require_module('phabricator', 'applications/files/exception/configuration');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown by storage engines to indicate an configuration error which should
|
||||
* abort the storage attempt, as opposed to a transient storage error which
|
||||
* should be retried on other engines.
|
||||
*
|
||||
* @group files
|
||||
*/
|
||||
final class PhabricatorFileStorageConfigurationException extends Exception {
|
||||
|
||||
}
|
10
src/applications/files/exception/configuration/__init__.php
Normal file
10
src/applications/files/exception/configuration/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorFileStorageConfigurationException.php');
|
|
@ -93,22 +93,24 @@ final class PhabricatorFile extends PhabricatorFileDAO {
|
|||
|
||||
$data_handle = null;
|
||||
$engine_identifier = null;
|
||||
$exceptions = array();
|
||||
foreach ($engines as $engine) {
|
||||
$engine_class = get_class($engine);
|
||||
try {
|
||||
// Perform the actual write.
|
||||
$data_handle = $engine->writeFile($data, $params);
|
||||
if (!$data_handle || strlen($data_handle) > 255) {
|
||||
// This indicates an improperly implemented storage engine.
|
||||
throw new Exception(
|
||||
"Storage engine '{$engine}' executed writeFile() but did not ".
|
||||
"return a valid handle ('{$data_handle}') to the data: it must ".
|
||||
"be nonempty and no longer than 255 characters.");
|
||||
throw new PhabricatorFileStorageConfigurationException(
|
||||
"Storage engine '{$engine_class}' executed writeFile() but did ".
|
||||
"not return a valid handle ('{$data_handle}') to the data: it ".
|
||||
"must be nonempty and no longer than 255 characters.");
|
||||
}
|
||||
|
||||
$engine_identifier = $engine->getEngineIdentifier();
|
||||
if (!$engine_identifier || strlen($engine_identifier) > 32) {
|
||||
throw new Exception(
|
||||
"Storage engine '{$engine}' returned an improper engine ".
|
||||
throw new PhabricatorFileStorageConfigurationException(
|
||||
"Storage engine '{$engine_class}' returned an improper engine ".
|
||||
"identifier '{$engine_identifier}': it must be nonempty ".
|
||||
"and no longer than 32 characters.");
|
||||
}
|
||||
|
@ -117,14 +119,24 @@ final class PhabricatorFile extends PhabricatorFileDAO {
|
|||
// places.
|
||||
break;
|
||||
} catch (Exception $ex) {
|
||||
if ($ex instanceof PhabricatorFileStorageConfigurationException) {
|
||||
// If an engine is outright misconfigured (or misimplemented), raise
|
||||
// that immediately since it probably needs attention.
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
// If an engine doesn't work, keep trying all the other valid engines
|
||||
// in case something else works.
|
||||
phlog($ex);
|
||||
|
||||
$exceptions[] = $ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data_handle) {
|
||||
throw new Exception("All storage engines failed to write file!");
|
||||
throw new PhutilAggregateException(
|
||||
"All storage engines failed to write file:",
|
||||
$exceptions);
|
||||
}
|
||||
|
||||
$file_name = idx($params, 'name');
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/files/exception/configuration');
|
||||
phutil_require_module('phabricator', 'applications/files/exception/upload');
|
||||
phutil_require_module('phabricator', 'applications/files/storage/base');
|
||||
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||
|
@ -14,6 +15,7 @@ phutil_require_module('phabricator', 'infrastructure/env');
|
|||
phutil_require_module('phabricator', 'infrastructure/util/hash');
|
||||
|
||||
phutil_require_module('phutil', 'error');
|
||||
phutil_require_module('phutil', 'error/aggregate');
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
phutil_require_module('phutil', 'filesystem/tempfile');
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
font-size: 14px;
|
||||
background: #efefef;
|
||||
padding: 1em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.aphront-exception-dialog .exception-trace {
|
||||
|
|
Loading…
Reference in a new issue