/** * Static s_display_error */ static function generic_display_error(exception $ex) { $title = $ex->getMessage(); $err_no = $ex->getCode(); if (!class_exists('loader') || class_exists('loader') && !loader::in_ajax()) { header('', true, 500); $message = '<style>* {font: 0.97em verdana;} a {text-decoration:none;background:#EFEFEF;padding:4px;} a:hover{background: red;}</style><h1>Ups! We have an error here.</h1>'; $subject = "Error " . " at " . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; $message .= 'Visit <a href="/">index</a> page.<br/><br/>'; echo $message; // if debug if (class_exists('core') && core::is_debug()) { echo '<br/>Error : ' . $title . ' : ' . $err_no; echo '<br/><br/>' . nl2br($ex->getTraceAsString()); } } }
/** * Sends an errormessage (html) to the user * * @access public * @static * @param exception $exception Instanz of an exception */ public function showError($exception) { /* flush cache */ ob_clean(); ob_start(); /* display html */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>phpMedaDB :: Exception</title> <style type="text/css"> <!-- body { font-size:12px; font-family:monospace; } h1 { font-size:18px; color:red; } .phpmediadb-body-exception { background-color:#FFFFCC; border:1px dashed grey; margin-bottom:10px; padding:5px; } .phpmediadb-body-exception-code { background-color:#FAFAFA; border:1px dotted grey; margin:10px; padding:5px; } .phpmediadb-body-exception-copyright { text-align:right; } --> </style> </head> <body> <div class="phpmediadb-body-exception"> <h1>Ouch, got an exception...</h1> Sorry but I was not able to complete your request. Please try again. <?php if (constant('PHPMEDIADB_SYSTEM_DEBUGLEVEL') >= 1) { ?> <br /><br /> <b>Exception Details:</b> <div class="phpmediadb-body-exception-code"><pre><?php echo htmlentities($exception->getMessage()); ?> </pre></div> <?php } ?> </div> <?php if (constant('PHPMEDIADB_SYSTEM_DEBUGLEVEL') >= 2) { ?> <div class="phpmediadb-body-exception"> <h1>Debug</h1> <b>Stack trace:</b><br /> <div class="phpmediadb-body-exception-code"><pre><?php echo htmlentities($exception->getTraceAsString()); ?> </pre></div> <br /> <b>File:</b> <?php echo htmlentities($exception->getFile()); ?> <b>Line:</b> <?php echo htmlentities($exception->getLine()); ?> </div> <?php } ?> <div class="phpmediadb-body-exception-copyright"> phpMediaDB :: The media database<br /> Version <?php echo PHPMEDIADB_SYSTEM_VERSION; ?> </div> </body> </html><?php }
/** * Displays an exception in HTML, and exists. Includes the exception * trace in an HTML comment, and a readable error string along with the * exception message. * @param exception $e Exception */ public static function handle_exception($e) { // Display actual trace in HTML comment. There shouldn't be any // security-sensitive information in the trace, so this can be // displayed even on live server (I hope). if (debugging('', DEBUG_DEVELOPER)) { global $CFG; print "<pre class='forumng-stacktrace'>"; print htmlspecialchars(str_replace($CFG->dirroot, '', $e->getTraceAsString())); print "</pre>"; } else { print "<!--\n"; print $e->getTraceAsString(); // Not escaped, I think this is correct... print "\n-->"; } // Make a short version of the trace string for log $minitrace = self::get_minitrace_part($e->getFile(), $e->getLine()); foreach ($e->getTrace() as $entry) { $minitrace .= ' ' . self::get_minitrace_part($entry['file'], $entry['line']); } $minitrace = shorten_text($minitrace, 120, true); $message = shorten_text($e->getMessage(), 120, true); global $FULLME, $USER, $CFG; $url = str_replace($CFG->wwwroot . '/mod/forumng/', '', $FULLME); add_to_log(0, 'forumng', 'error', $url, "{$message} / {$minitrace}", 0, $USER->id); // Error to user with just the message print_error('error_exception', 'forumng', '', $e->getMessage()); }
/** * Display a command prompt, block on input from STDIN, then parse and execute the specified commands. * * Multiple processes share a single command prompt by accessing a semaphore identified by the current application. * This method will block the process while it waits for the mutex, and then again while it waits for input on STDIN. * * The text of the prompt itself will be written when get_text_prompt() is called. Custom prompts for a given $method * can be added to the $prompts array. * * Several commands are built-in, and additional commands can be added with addParser(). * * Parsers can either: * 1. Continue from the prompt. * 2. Abort from the prompt. Call any interrupt_callable that may be registered for this $method. * 3. Take some action or perform some activity and then return to the same prompt for additional commands. * * @param $method * @param $args * @return bool|int|mixed|null * @throws Exception */ public function prompt($method, $args) { if (!is_resource($this->shm)) { return true; } // The single debug shell is shared across the parent and all worker processes. Use a mutex to serialize // access to the shell. If the mutex isn't owned by this process, this will block until this process acquires it. $this->mutex_acquire(); if (!$this->is_breakpoint_active($method)) { $this->mutex_release(); return true; } // Pass a simple print-line closure to parsers to use instead of just "echo" or "print" $printer = function ($message, $maxlen = null) { if (empty($message)) { return; } if ($maxlen && strlen($message) > $maxlen) { $message = substr($message, 0, $maxlen - 3) . '...'; } $message = str_replace(PHP_EOL, PHP_EOL . ' ', $message); echo " {$message}\n\n"; }; try { $this->print_banner(); $pid = getmypid(); $prompt = $this->get_text_prompt($method, $args); $break = false; // We have to clear the buffer of any input that occurred in the terminal in the space after they submitted their last // command and before this new prompt. Otherwise it'll be read from fgets below and probably ruin everything. stream_set_blocking(STDIN, 0); while (fgets(STDIN)) { continue; } stream_set_blocking(STDIN, 1); // Commands that set $break=true will continue forward from the command prompt. // Otherwise it will just do the action (or display an error) and then repeat the prompt while (!$break) { echo $prompt; $input = trim(fgets(STDIN)); $input = preg_replace('/\\s+/', ' ', $input); $matches = false; $message = ''; // Use the familiar bash !! to re-run the last command if (substr($input, -2) == '!!') { $input = $this->debug_state('last'); } elseif (!empty($input)) { $this->debug_state('last', $input); } // Validate the input as an expression $matches = array(); foreach ($this->parsers as $parser) { if (preg_match($parser['regex'], $input, $matches) == 1) { $break = $parser['closure']($matches, $printer); break; } } if ($matches) { continue; } // If one of the parsers didn't catch the message // fall through to the built-in commands switch (strtolower($input)) { case 'help': $out = array(); $out[] = 'For the PHP Simple Daemon debugging guide, see: '; $out[] = 'https://github.com/shaneharter/PHP-Daemon/wiki/Debugging-Workers'; $out[] = ''; $out[] = 'Available Commands:'; $out[] = 'y Step to the next break point'; $out[] = 'n Interrupt'; $out[] = ''; $out[] = 'capture Call the current method and capture its return value. Will print_r the return value and return a prompt.'; $out[] = 'end End the debugging session, continue the daemon as normal.'; $out[] = 'help Print This Help'; $out[] = 'kill Kill the daemon and all of its worker processes.'; $out[] = 'skip Skip this breakpoint from now on.'; $out[] = 'shutdown End Debugging and Gracefully shutdown the daemon after the current loop_interval.'; $out[] = 'trace Print A Stack Trace'; if (is_callable($this->indent_callback)) { $out[] = 'indent [y|n] When turned-on, indentation will be used to group messages from the same call in a column so you can easily match them together.'; } $out[] = ''; foreach ($this->parsers as $parser) { $out[] = sprintf('%s%s', str_pad($parser['command'], 18, ' ', STR_PAD_RIGHT), $parser['description']); } $out[] = ''; $out[] = '!! Repeat previous command'; $printer(implode(PHP_EOL, $out)); break; case 'indent y': $this->debug_state('indent', true); $printer('Indent enabled'); break; case 'indent n': $this->debug_state('indent', false); $printer('Indent disabled'); break; case 'show args': $printer(print_r($args, true)); break; case 'shutdown': //$this->daemon->shutdown(); $printer("Shutdown In Progress... Use `end` command to cease debugging until shutdown is complete."); $break = true; break; case 'trace': $e = new exception(); $printer($e->getTraceAsString()); break; case 'end': $this->debug_state('enabled', false); $break = true; $printer('Debugging Ended..'); $input = true; break; case 'skip': $this->debug_state("skip_{$method}", true); $printer('Breakpoint "' . $method . '" Turned Off..'); $break = true; $input = true; break; case 'kill': @fclose(STDOUT); @fclose(STDERR); @exec('ps -C "php ' . Core_Daemon::get('filename') . '" -o pid= | xargs kill -9 '); break; case 'capture': $backtrace = debug_backtrace(); if ($backtrace[1]['function'] !== '__call' || $method == self::CAPTURE) { $printer('Cannot capture this :('); break; } $input = self::CAPTURE; $break = true; break; case 'y': $input = self::CONT; $break = true; break; case 'n': $input = self::ABORT; $break = true; break; default: if ($input) { $printer("Unknown Command! See `help` for list of commands."); } } } } catch (Exception $e) { $this->mutex_release(); throw $e; } $this->mutex_release(); return $input; }