Example #1
0
 private static function initializeCommonEnvironment()
 {
     PhutilErrorHandler::initialize();
     self::buildConfigurationSourceStack();
     // Force a valid timezone. If both PHP and Phabricator configuration are
     // invalid, use UTC.
     $tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
     if ($tz) {
         @date_default_timezone_set($tz);
     }
     $ok = @date_default_timezone_set(date_default_timezone_get());
     if (!$ok) {
         date_default_timezone_set('UTC');
     }
     // Prepend '/support/bin' and append any paths to $PATH if we need to.
     $env_path = getenv('PATH');
     $phabricator_path = dirname(phutil_get_library_root('phabricator'));
     $support_path = $phabricator_path . '/support/bin';
     $env_path = $support_path . PATH_SEPARATOR . $env_path;
     $append_dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
     if (!empty($append_dirs)) {
         $append_path = implode(PATH_SEPARATOR, $append_dirs);
         $env_path = $env_path . PATH_SEPARATOR . $append_path;
     }
     putenv('PATH=' . $env_path);
     // Write this back into $_ENV, too, so ExecFuture picks it up when creating
     // subprocess environments.
     $_ENV['PATH'] = $env_path;
     PhabricatorEventEngine::initialize();
     $translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
     PhutilTranslator::getInstance()->setLanguage($translation->getLanguage())->addTranslations($translation->getTranslations());
 }
 public static function registerErrorHandler()
 {
     // NOTE: This forces PhutilReadableSerializer to load, so that we are
     // able to handle errors which fire from inside autoloaders (PHP will not
     // reenter autoloaders).
     PhutilReadableSerializer::printableValue(null);
     PhutilErrorHandler::setErrorListener(array('DarkConsoleErrorLogPluginAPI', 'handleErrors'));
 }
Example #3
0
/**
 * libphutil log function for development debugging. Takes any argument and
 * forwards it to registered listeners. This is essentially a more powerful
 * version of ##error_log()##.
 *
 * @param wild Any value you want printed to the error log or other registered
 *             logs/consoles.
 * @param ...  Other values to be logged.
 * @return wild Passed $value.
 */
function phlog($value)
{
    // Get the caller information
    $trace = debug_backtrace();
    $metadata = array('file' => $trace[0]['file'], 'line' => $trace[0]['line'], 'trace' => $trace);
    foreach (func_get_args() as $event) {
        PhutilErrorHandler::dispatchErrorMessage($event instanceof Exception ? PhutilErrorHandler::EXCEPTION : PhutilErrorHandler::PHLOG, $event, $metadata);
    }
    return $value;
}
 public function testProxyException()
 {
     $a = new Exception('a');
     $b = new PhutilProxyException('b', $a);
     $c = new PhutilProxyException('c', $b);
     $this->assertEqual($a, $b->getPrevious());
     $this->assertEqual($a, PhutilErrorHandler::getRootException($b));
     $this->assertEqual($a, PhutilErrorHandler::getPreviousException($b));
     $this->assertEqual($a, PhutilErrorHandler::getRootException($c));
     $this->assertEqual($b, PhutilErrorHandler::getPreviousException($c));
 }
Example #5
0
function phutil_daemon_error_listener($event, $value, array $metadata)
{
    $message = idx($metadata, 'default_message');
    if ($message) {
        fwrite(STDERR, $message . "\n");
    }
    if (idx($metadata, 'trace')) {
        $trace = PhutilErrorHandler::formatStacktrace($metadata['trace']);
        fwrite(STDERR, $trace . "\n");
    }
}
Example #6
0
function phutil_daemon_error_listener($event, $value, array $metadata)
{
    $console = PhutilConsole::getConsole();
    $message = idx($metadata, 'default_message');
    if ($message) {
        $console->writeErr("%s\n", $message);
    }
    if (idx($metadata, 'trace')) {
        $trace = PhutilErrorHandler::formatStacktrace($metadata['trace']);
        $console->writeErr("%s\n", $trace);
    }
}
Example #7
0
/**
 * libphutil log function for development debugging. Takes any argument and
 * forwards it to registered listeners. This is essentially a more powerful
 * version of ##error_log()##.
 *
 * NOTE: You must call ##PhutilErrorHandler::initialize()## before this will do
 * anything.
 *
 * @param wild Any value you want printed to the error log or other registered
 *             logs/consoles.
 * @return wild Passed $value.
 * @group error
 */
function phlog($value)
{
    if (!PhutilErrorHandler::hasInitialized()) {
        throw new Exception("Call to phlog() before PhutilErrorHandler::initialize()!");
    }
    // Get the caller information
    $trace = debug_backtrace();
    $file = $trace[0]['file'];
    $line = $trace[0]['line'];
    PhutilErrorHandler::dispatchErrorMessage($value instanceof Exception ? PhutilErrorHandler::EXCEPTION : PhutilErrorHandler::PHLOG, $value, array('file' => $file, 'line' => $line, 'trace' => $trace));
    return $value;
}
function __phutil_init_script__()
{
    // Adjust the runtime language configuration to be reasonable and inline with
    // expectations. We do this first, then load libraries.
    // There may be some kind of auto-prepend script configured which starts an
    // output buffer. Discard any such output buffers so messages can be sent to
    // stdout (if a user wants to capture output from a script, there are a large
    // number of ways they can accomplish it legitimately; historically, we ran
    // into this on only one install which had some bizarre configuration, but it
    // was difficult to diagnose because the symptom is "no messages of any
    // kind").
    while (ob_get_level() > 0) {
        ob_end_clean();
    }
    error_reporting(E_ALL | E_STRICT);
    $config_map = array('display_errors' => true, 'log_errors' => true, 'error_log' => null, 'xdebug.max_nesting_level' => PHP_INT_MAX, 'memory_limit' => -1);
    foreach ($config_map as $config_key => $config_value) {
        ini_set($config_key, $config_value);
    }
    if (!ini_get('date.timezone')) {
        // If the timezone isn't set, PHP issues a warning whenever you try to parse
        // a date (like those from Git or Mercurial logs), even if the date contains
        // timezone information (like "PST" or "-0700") which makes the
        // environmental timezone setting is completely irrelevant. We never rely on
        // the system timezone setting in any capacity, so prevent PHP from flipping
        // out by setting it to a safe default (UTC) if it isn't set to some other
        // value.
        date_default_timezone_set('UTC');
    }
    // Adjust `include_path`.
    ini_set('include_path', implode(PATH_SEPARATOR, array(dirname(dirname(__FILE__)) . '/externals/includes', ini_get('include_path'))));
    // Disable the insanely dangerous XML entity loader by default.
    if (function_exists('libxml_disable_entity_loader')) {
        libxml_disable_entity_loader(true);
    }
    // Now, load libphutil.
    $root = dirname(dirname(__FILE__));
    require_once $root . '/src/__phutil_library_init__.php';
    PhutilErrorHandler::initialize();
    // If possible, install a signal handler for SIGHUP which prints the current
    // backtrace out to a named file. This is particularly helpful in debugging
    // hung/spinning processes.
    if (function_exists('pcntl_signal')) {
        pcntl_signal(SIGHUP, '__phutil_signal_handler__');
    }
}
 private static function initializeCommonEnvironment()
 {
     PhutilErrorHandler::initialize();
     self::buildConfigurationSourceStack();
     // Force a valid timezone. If both PHP and Phabricator configuration are
     // invalid, use UTC.
     $tz = self::getEnvConfig('phabricator.timezone');
     if ($tz) {
         @date_default_timezone_set($tz);
     }
     $ok = @date_default_timezone_set(date_default_timezone_get());
     if (!$ok) {
         date_default_timezone_set('UTC');
     }
     // Prepend '/support/bin' and append any paths to $PATH if we need to.
     $env_path = getenv('PATH');
     $phabricator_path = dirname(phutil_get_library_root('phabricator'));
     $support_path = $phabricator_path . '/support/bin';
     $env_path = $support_path . PATH_SEPARATOR . $env_path;
     $append_dirs = self::getEnvConfig('environment.append-paths');
     if (!empty($append_dirs)) {
         $append_path = implode(PATH_SEPARATOR, $append_dirs);
         $env_path = $env_path . PATH_SEPARATOR . $append_path;
     }
     putenv('PATH=' . $env_path);
     // Write this back into $_ENV, too, so ExecFuture picks it up when creating
     // subprocess environments.
     $_ENV['PATH'] = $env_path;
     // If an instance identifier is defined, write it into the environment so
     // it's available to subprocesses.
     $instance = self::getEnvConfig('cluster.instance');
     if (strlen($instance)) {
         putenv('PHABRICATOR_INSTANCE=' . $instance);
         $_ENV['PHABRICATOR_INSTANCE'] = $instance;
     }
     PhabricatorEventEngine::initialize();
     // TODO: Add a "locale.default" config option once we have some reasonable
     // defaults which aren't silly nonsense.
     self::setLocaleCode('en_US');
 }
Example #10
0
/**
 * libphutil log function for development debugging. Takes any argument and
 * forwards it to registered listeners. This is essentially a more powerful
 * version of `error_log()`.
 *
 * @param  wild  Any value you want printed to the error log or other registered
 *               logs/consoles.
 * @param  ...   Other values to be logged.
 * @return wild  Passed $value.
 */
function phlog($value)
{
    // Get the caller information.
    $trace = debug_backtrace();
    $metadata = array('file' => $trace[0]['file'], 'line' => $trace[0]['line'], 'trace' => $trace);
    foreach (func_get_args() as $event) {
        $data = $metadata;
        if ($event instanceof Exception) {
            $type = PhutilErrorHandler::EXCEPTION;
            // If this is an exception, proxy it and generate a composite trace which
            // shows both where the phlog() was called and where the exception was
            // originally thrown from.
            $proxy = new PhutilProxyException('', $event);
            $trace = PhutilErrorHandler::getExceptionTrace($proxy);
            $data['trace'] = $trace;
        } else {
            $type = PhutilErrorHandler::PHLOG;
        }
        PhutilErrorHandler::dispatchErrorMessage($type, $event, $data);
    }
    return $value;
}
Example #11
0
 public static function errorListener($event, $value, array $metadata)
 {
     // If the caller has redirected the error log to a file, PHP won't output
     // messages to stderr, so the overseer can't capture them. Install a
     // listener which just  echoes errors to stderr, so the overseer is always
     // aware of errors.
     $console = PhutilConsole::getConsole();
     $message = idx($metadata, 'default_message');
     if ($message) {
         $console->writeErr("%s\n", $message);
     }
     if (idx($metadata, 'trace')) {
         $trace = PhutilErrorHandler::formatStacktrace($metadata['trace']);
         $console->writeErr("%s\n", $trace);
     }
 }
 /**
  * Provide an optional listener callback which will receive all errors,
  * exceptions and debugging messages. It can then print them to a web console,
  * for example.
  *
  * See @{function:phutil_error_listener_example} for details about the
  * callback parameters and operation.
  *
  * @return void
  * @task config
  */
 public static function setErrorListener($listener)
 {
     self::$errorListener = $listener;
 }
Example #13
0
 // Append any paths to $PATH if we need to.
 $paths = PhabricatorEnv::getEnvConfig('environment.append-paths');
 if (!empty($paths)) {
     $current_env_path = getenv('PATH');
     $new_env_paths = implode(':', $paths);
     putenv('PATH=' . $current_env_path . ':' . $new_env_paths);
 }
 // This is the earliest we can get away with this, we need env config first.
 PhabricatorAccessLog::init();
 $access_log = PhabricatorAccessLog::getLog();
 if ($access_log) {
     $access_log->setData(array('R' => idx($_SERVER, 'HTTP_REFERER', '-'), 'r' => idx($_SERVER, 'REMOTE_ADDR', '-'), 'M' => idx($_SERVER, 'REQUEST_METHOD', '-')));
 }
 DarkConsoleXHProfPluginAPI::hookProfiler();
 PhutilErrorHandler::initialize();
 PhutilErrorHandler::setErrorListener(array('DarkConsoleErrorLogPluginAPI', 'handleErrors'));
 foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
     phutil_load_library($library);
 }
 if (PhabricatorEnv::getEnvConfig('phabricator.setup')) {
     try {
         PhabricatorSetup::runSetup();
     } catch (Exception $ex) {
         echo "EXCEPTION!\n";
         echo $ex;
     }
     return;
 }
 phabricator_detect_bad_base_uri();
 $translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
 PhutilTranslator::getInstance()->setLanguage($translation->getLanguage())->addTranslations($translation->getTranslations());
 * 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.
 */
$include_path = ini_get('include_path');
ini_set('include_path', $include_path . ':' . dirname(__FILE__) . '/../../');
require_once dirname(dirname(__FILE__)) . '/conf/__init_conf__.php';
$env = isset($_SERVER['PHABRICATOR_ENV']) ? $_SERVER['PHABRICATOR_ENV'] : getenv('PHABRICATOR_ENV');
if (!$env) {
    echo "Define PHABRICATOR_ENV before running this script.\n";
    exit(1);
}
$conf = phabricator_read_config_file($env);
$conf['phabricator.env'] = $env;
phutil_require_module('phabricator', 'infrastructure/env');
PhabricatorEnv::setEnvConfig($conf);
phutil_load_library('arcanist/src');
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
    phutil_load_library($library);
}
PhutilErrorHandler::initialize();
$tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
if ($tz) {
    date_default_timezone_set($tz);
}
Example #15
0
}
PhutilErrorHandler::initialize();
function phutil_daemon_error_listener($event, $value, array $metadata)
{
    $message = idx($metadata, 'default_message');
    if ($message) {
        fwrite(STDERR, $message);
    }
}
if ($echo_to_stderr) {
    // If the caller has used "--log" to redirect the error log to a file, PHP
    // won't output it to stderr so the overseer can't capture it and won't
    // be able to send it to the web console. Install a listener which just echoes
    // errors to stderr, so we always get all the messages in the log and over
    // stdio, so they'll show up in the web console.
    PhutilErrorHandler::setErrorListener('phutil_daemon_error_listener');
}
$daemon = array_shift($argv);
if (!$daemon) {
    $args->printHelpAndExit();
}
$daemon = newv($daemon, array($argv));
if ($trace_mode) {
    $daemon->setTraceMode();
}
if ($trace_memory) {
    $daemon->setTraceMemory();
}
if ($verbose) {
    $daemon->setVerbose(true);
}
Example #16
0
/**
 * Warns about use of deprecated behavior.
 */
function phutil_deprecated($what, $why)
{
    PhutilErrorHandler::dispatchErrorMessage(PhutilErrorHandler::DEPRECATED, $what, array('why' => $why));
}
Example #17
0
 public function __construct()
 {
     PhutilErrorHandler::addErrorTrap($this);
 }