r14625 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r14624‎ | r14625 | r14626 >
Date:23:07, 6 June 2006
Author:tstarling
Status:old
Tags:
Comment:
Some initial work on exceptions. More to follow.
Modified paths:
  • /trunk/phase3/includes/Database.php (modified) (history)
  • /trunk/phase3/includes/DatabaseOracle.php (modified) (history)
  • /trunk/phase3/includes/DatabasePostgreSQL.php (modified) (history)
  • /trunk/phase3/includes/Exception.php (added) (history)
  • /trunk/phase3/includes/LoadBalancer.php (modified) (history)
  • /trunk/phase3/includes/Setup.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/DatabaseOracle.php
@@ -52,7 +52,7 @@
5353 */
5454 function open( $server, $user, $password, $dbName ) {
5555 if ( !function_exists( 'oci_connect' ) ) {
56 - wfDie( "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n" );
 56+ throw new DBConnectionError( $this, "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n" );
5757 }
5858 $this->close();
5959 $this->mServer = $server;
@@ -137,7 +137,7 @@
138138
139139 function freeResult( $res ) {
140140 if (!oci_free_statement($res)) {
141 - wfDebugDieBacktrace( "Unable to free Oracle result\n" );
 141+ throw new DBUnexpectedError( $this, "Unable to free Oracle result\n" );
142142 }
143143 unset($this->mFetchID[$res]);
144144 unset($this->mFetchCache[$res]);
@@ -385,7 +385,7 @@
386386 # DELETE where the condition is a join
387387 function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
388388 if ( !$conds ) {
389 - wfDebugDieBacktrace( 'Database::deleteJoin() called with empty $conds' );
 389+ throw new DBUnexpectedError( $this, 'Database::deleteJoin() called with empty $conds' );
390390 }
391391
392392 $delTable = $this->tableName( $delTable );
@@ -467,7 +467,7 @@
468468 "Query: $sql\n" .
469469 "Function: $fname\n" .
470470 "Error: $errno $error\n";
471 - wfDebugDieBacktrace($message);
 471+ throw new DBUnexpectedError($this, $message);
472472 }
473473
474474 /**
Index: trunk/phase3/includes/Setup.php
@@ -43,6 +43,12 @@
4444
4545 $fname = 'Setup.php';
4646 wfProfileIn( $fname );
 47+
 48+wfProfileIn( $fname.'-exception' );
 49+require_once( 'Exception.php' );
 50+wfInstallExceptionHandler();
 51+wfProfileOut( $fname.'-exception' );
 52+
4753 wfProfileIn( $fname.'-includes' );
4854
4955 require_once( 'AutoLoader.php' );
Index: trunk/phase3/includes/DatabasePostgreSQL.php
@@ -45,7 +45,7 @@
4646 function open( $server, $user, $password, $dbName ) {
4747 # Test for PostgreSQL support, to avoid suppressed fatal error
4848 if ( !function_exists( 'pg_connect' ) ) {
49 - wfDie( "PostgreSQL functions missing, have you compiled PHP with the --with-pgsql option?\n" );
 49+ throw new DBConnectionError( $this, "PostgreSQL functions missing, have you compiled PHP with the --with-pgsql option?\n" );
5050 }
5151
5252 global $wgDBschema;
@@ -101,7 +101,7 @@
102102
103103 function freeResult( $res ) {
104104 if ( !@pg_free_result( $res ) ) {
105 - wfDebugDieBacktrace( "Unable to free PostgreSQL result\n" );
 105+ throw new DBUnexpectedError($this, "Unable to free PostgreSQL result\n" );
106106 }
107107 }
108108
@@ -113,7 +113,7 @@
114114 # hashar : not sure if the following test really trigger if the object
115115 # fetching failled.
116116 if( pg_last_error($this->mConn) ) {
117 - wfDebugDieBacktrace( 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
 117+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
118118 }
119119 return $row;
120120 }
@@ -121,7 +121,7 @@
122122 function fetchRow( $res ) {
123123 @$row = pg_fetch_array( $res );
124124 if( pg_last_error($this->mConn) ) {
125 - wfDebugDieBacktrace( 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
 125+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
126126 }
127127 return $row;
128128 }
@@ -129,7 +129,7 @@
130130 function numRows( $res ) {
131131 @$n = pg_num_rows( $res );
132132 if( pg_last_error($this->mConn) ) {
133 - wfDebugDieBacktrace( 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
 133+ throw new DBUnexpectedError($this, 'SQL error: ' . htmlspecialchars( pg_last_error($this->mConn) ) );
134134 }
135135 return $n;
136136 }
@@ -183,13 +183,13 @@
184184 }
185185
186186 function fieldInfo( $table, $field ) {
187 - wfDebugDieBacktrace( 'Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre' );
 187+ throw new DBUnexpectedError($this, 'Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre' );
188188 /*
189189 $res = $this->query( "SELECT * FROM '$table' LIMIT 1" );
190190 $n = pg_num_fields( $res );
191191 for( $i = 0; $i < $n; $i++ ) {
192192 // FIXME
193 - wfDebugDieBacktrace( "Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre" );
 193+ throw new DBUnexpectedError($this, "Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre" );
194194 $meta = mysql_fetch_field( $res, $i );
195195 if( $field == $meta->name ) {
196196 return $meta;
@@ -328,7 +328,7 @@
329329 # DELETE where the condition is a join
330330 function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
331331 if ( !$conds ) {
332 - wfDebugDieBacktrace( 'Database::deleteJoin() called with empty $conds' );
 332+ throw new DBUnexpectedError($this, 'Database::deleteJoin() called with empty $conds' );
333333 }
334334
335335 $delTable = $this->tableName( $delTable );
@@ -404,7 +404,7 @@
405405 "Query: $sql\n" .
406406 "Function: $fname\n" .
407407 "Error: $errno $error\n";
408 - wfDebugDieBacktrace($message);
 408+ throw new DBUnexpectedError($this, $message);
409409 }
410410
411411 /**
Index: trunk/phase3/includes/LoadBalancer.php
@@ -436,7 +436,7 @@
437437 */
438438 function reallyOpenConnection( &$server ) {
439439 if( !is_array( $server ) ) {
440 - wfDebugDieBacktrace( 'You must update your load-balancing configuration. See DefaultSettings.php entry for $wgDBservers.' );
 440+ throw new MWException( 'You must update your load-balancing configuration. See DefaultSettings.php entry for $wgDBservers.' );
441441 }
442442
443443 extract( $server );
@@ -477,7 +477,8 @@
478478 } else {
479479 $conn->failFunction( false );
480480 }
481 - $conn->reportConnectionError( "{$this->mLastError} ({$conn->mServer})" );
 481+ $server = $conn->getProperty( 'mServer' );
 482+ $conn->reportConnectionError( "{$this->mLastError} ({$server})" );
482483 }
483484 $reporting = false;
484485 }
Index: trunk/phase3/includes/Exception.php
@@ -0,0 +1,172 @@
 2+<?php
 3+
 4+class MWException extends Exception
 5+{
 6+ function useOutputPage() {
 7+ return !empty( $GLOBALS['wgFullyInitialised'] );
 8+ }
 9+
 10+ function useMessageCache() {
 11+ global $wgLang;
 12+ return is_object( $wgLang );
 13+ }
 14+
 15+ function msg( $key, $fallback /*[, params...] */ ) {
 16+ $args = array_slice( func_get_args(), 2 );
 17+ if ( $this->useMessageCache() ) {
 18+ return wfMsgReal( $key, $args );
 19+ } else {
 20+ return wfMsgReplaceArgs( $fallback, $args );
 21+ }
 22+ }
 23+
 24+ function getHTML() {
 25+ return '<p>' . htmlspecialchars( $this->getMessage() ) .
 26+ '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
 27+ "</p>\n";
 28+ }
 29+
 30+ function getText() {
 31+ return $this->getMessage() .
 32+ "\nBacktrace:\n" . $this->getTraceAsString() . "\n";
 33+ }
 34+
 35+ function getPageTitle() {
 36+ if ( $this->useMessageCache() ) {
 37+ return wfMsg( 'internalerror' );
 38+ } else {
 39+ global $wgSitename;
 40+ return "$wgSitename error";
 41+ }
 42+ }
 43+
 44+ function reportHTML() {
 45+ global $wgOut;
 46+ if ( $this->useOutputPage() ) {
 47+ $wgOut->setPageTitle( $this->getPageTitle() );
 48+ $wgOut->setRobotpolicy( "noindex,nofollow" );
 49+ $wgOut->setArticleRelated( false );
 50+ $wgOut->enableClientCache( false );
 51+ $wgOut->redirect( '' );
 52+ $wgOut->clearHTML();
 53+ $wgOut->addHTML( $this->getHTML() );
 54+ $wgOut->output();
 55+ } else {
 56+ echo $this->htmlHeader();
 57+ echo $this->getHTML();
 58+ echo $this->htmlFooter();
 59+ }
 60+ }
 61+
 62+ function reportText() {
 63+ echo $this->getText();
 64+ }
 65+
 66+ function report() {
 67+ global $wgCommandLineMode;
 68+ if ( $wgCommandLineMode ) {
 69+ $this->reportText();
 70+ } else {
 71+ $this->reportHTML();
 72+ }
 73+ }
 74+
 75+ function htmlHeader() {
 76+ global $wgLogo, $wgSitename, $wgOutputEncoding;
 77+
 78+ if ( !headers_sent() ) {
 79+ header( 'HTTP/1.0 500 Internal Server Error' );
 80+ header( 'Content-type: text/html; charset='.$wgOutputEncoding );
 81+ /* Don't cache error pages! They cause no end of trouble... */
 82+ header( 'Cache-control: none' );
 83+ header( 'Pragma: nocache' );
 84+ }
 85+ $title = $this->getPageTitle();
 86+ echo "<html>
 87+ <head>
 88+ <title>$title</title>
 89+ </head>
 90+ <body>
 91+ <h1><img src='$wgLogo' style='float:left;margin-right:1em' alt=''>$title</h1>
 92+ ";
 93+ }
 94+
 95+ function htmlFooter() {
 96+ echo "</body></html>";
 97+ }
 98+}
 99+
 100+/**
 101+ * Exception class which takes an HTML error message, and does not
 102+ * produce a backtrace. Replacement for OutputPage::fatalError().
 103+ */
 104+class FatalError extends MWException {
 105+ function getHTML() {
 106+ return $this->getMessage();
 107+ }
 108+
 109+ function getText() {
 110+ return $this->getMessage();
 111+ }
 112+}
 113+
 114+/**
 115+ * Install an exception handler for MediaWiki exception types.
 116+ */
 117+function wfInstallExceptionHandler() {
 118+ set_exception_handler( 'wfExceptionHandler' );
 119+}
 120+
 121+/**
 122+ * Report an exception to the user
 123+ */
 124+function wfReportException( Exception $e ) {
 125+ if ( is_a( $e, 'MWException' ) ) {
 126+ try {
 127+ $e->report();
 128+ } catch ( Exception $e2 ) {
 129+ // Exception occurred from within exception handler
 130+ // Show a simpler error message for the original exception,
 131+ // don't try to invoke report()
 132+ $message = "MediaWiki internal error.\n\n" .
 133+ "Original exception: " . $e->__toString() .
 134+ "\n\nException caught inside exception handler: " .
 135+ $e2->__toString() . "\n";
 136+
 137+ if ( !empty( $GLOBALS['wgCommandLineMode'] ) ) {
 138+ echo $message;
 139+ } else {
 140+ echo nl2br( htmlspecialchars( $message ) ). "\n";
 141+ }
 142+ }
 143+ } else {
 144+ echo $e->__toString();
 145+ }
 146+}
 147+
 148+/**
 149+ * Exception handler which simulates the appropriate catch() handling:
 150+ *
 151+ * try {
 152+ * ...
 153+ * } catch ( MWException $e ) {
 154+ *
 155+ * $e->report();
 156+ * } catch ( Exception $e ) {
 157+ * echo $e->__toString();
 158+ * }
 159+ */
 160+function wfExceptionHandler( $e ) {
 161+ wfReportException( $e );
 162+
 163+ // Final cleanup, similar to wfErrorExit()
 164+ try {
 165+ wfProfileClose();
 166+ logProfilingData();
 167+ } catch ( Exception $e ) {}
 168+
 169+ // Exit value should be nonzero for the benefit of shell jobs
 170+ exit( 1 );
 171+}
 172+
 173+?>
Index: trunk/phase3/includes/Database.php
@@ -24,8 +24,12 @@
2525 /** Maximum time to wait before retry */
2626 define( 'DEADLOCK_DELAY_MAX', 1500000 );
2727
 28+/******************************************************************************
 29+ * Utility classes
 30+ *****************************************************************************/
 31+
2832 class DBObject {
29 - var $mData;
 33+ public $mData;
3034
3135 function DBObject($data) {
3236 $this->mData = $data;
@@ -40,7 +44,191 @@
4145 }
4246 };
4347
 48+/******************************************************************************
 49+ * Error classes
 50+ *****************************************************************************/
 51+
4452 /**
 53+ * Database error base class
 54+ */
 55+class DBError extends MWException {
 56+ public $db;
 57+
 58+ /**
 59+ * Construct a database error
 60+ * @param Database $db The database object which threw the error
 61+ * @param string $error A simple error message to be used for debugging
 62+ */
 63+ function __construct( Database &$db, $error ) {
 64+ $this->db =& $db;
 65+ parent::__construct( $error );
 66+ }
 67+}
 68+
 69+class DBConnectionError extends DBError {
 70+ public $error;
 71+
 72+ function __construct( Database &$db, $error = 'unknown error' ) {
 73+ $msg = 'DB connection error';
 74+ if ( trim( $error ) != '' ) {
 75+ $msg .= ": $error";
 76+ }
 77+ $this->error = $error;
 78+ parent::__construct( $db, $msg );
 79+ }
 80+
 81+ function useOutputPage() {
 82+ // Not likely to work
 83+ return false;
 84+ }
 85+
 86+ function useMessageCache() {
 87+ // Not likely to work
 88+ return false;
 89+ }
 90+
 91+ function getText() {
 92+ return $this->getMessage() . "\n";
 93+ }
 94+
 95+ function getPageTitle() {
 96+ global $wgSitename;
 97+ return "$wgSitename has a problem";
 98+ }
 99+
 100+ function getHTML() {
 101+ global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgOutputEncoding;
 102+ global $wgSitename, $wgServer, $wgMessageCache, $wgLogo;
 103+
 104+ # I give up, Brion is right. Getting the message cache to work when there is no DB is tricky.
 105+ # Hard coding strings instead.
 106+
 107+ $noconnect = "<p><strong>Sorry! This site is experiencing technical difficulties.</strong></p><p>Try waiting a few minutes and reloading.</p><p><small>(Can't contact the database server: $1)</small></p>";
 108+ $mainpage = 'Main Page';
 109+ $searchdisabled = <<<EOT
 110+<p style="margin: 1.5em 2em 1em">$wgSitename search is disabled for performance reasons. You can search via Google in the meantime.
 111+<span style="font-size: 89%; display: block; margin-left: .2em">Note that their indexes of $wgSitename content may be out of date.</span></p>',
 112+EOT;
 113+
 114+ $googlesearch = "
 115+<!-- SiteSearch Google -->
 116+<FORM method=GET action=\"http://www.google.com/search\">
 117+<TABLE bgcolor=\"#FFFFFF\"><tr><td>
 118+<A HREF=\"http://www.google.com/\">
 119+<IMG SRC=\"http://www.google.com/logos/Logo_40wht.gif\"
 120+border=\"0\" ALT=\"Google\"></A>
 121+</td>
 122+<td>
 123+<INPUT TYPE=text name=q size=31 maxlength=255 value=\"$1\">
 124+<INPUT type=submit name=btnG VALUE=\"Google Search\">
 125+<font size=-1>
 126+<input type=hidden name=domains value=\"$wgServer\"><br /><input type=radio name=sitesearch value=\"\"> WWW <input type=radio name=sitesearch value=\"$wgServer\" checked> $wgServer <br />
 127+<input type='hidden' name='ie' value='$2'>
 128+<input type='hidden' name='oe' value='$2'>
 129+</font>
 130+</td></tr></TABLE>
 131+</FORM>
 132+<!-- SiteSearch Google -->";
 133+ $cachederror = "The following is a cached copy of the requested page, and may not be up to date. ";
 134+
 135+ # No database access
 136+ if ( is_object( $wgMessageCache ) ) {
 137+ $wgMessageCache->disable();
 138+ }
 139+
 140+ if ( trim( $this->error ) == '' ) {
 141+ $this->error = $this->db->getProperty('mServer');
 142+ }
 143+
 144+ $text = str_replace( '$1', $this->error, $noconnect );
 145+ $text .= wfGetSiteNotice();
 146+
 147+ if($wgUseFileCache) {
 148+ if($wgTitle) {
 149+ $t =& $wgTitle;
 150+ } else {
 151+ if($title) {
 152+ $t = Title::newFromURL( $title );
 153+ } elseif (@/**/$_REQUEST['search']) {
 154+ $search = $_REQUEST['search'];
 155+ return $searchdisabled .
 156+ str_replace( array( '$1', '$2' ), array( htmlspecialchars( $search ),
 157+ $wgInputEncoding ), $googlesearch );
 158+ } else {
 159+ $t = Title::newFromText( $mainpage );
 160+ }
 161+ }
 162+
 163+ $cache = new CacheManager( $t );
 164+ if( $cache->isFileCached() ) {
 165+ $msg = '<p style="color: red"><b>'.$msg."<br />\n" .
 166+ $cachederror . "</b></p>\n";
 167+
 168+ $tag = '<div id="article">';
 169+ $text = str_replace(
 170+ $tag,
 171+ $tag . $msg,
 172+ $cache->fetchPageText() );
 173+ }
 174+ }
 175+
 176+ return $text;
 177+ }
 178+}
 179+
 180+class DBQueryError extends DBError {
 181+ public $error, $errno, $sql, $fname;
 182+
 183+ function __construct( Database &$db, $error, $errno, $sql, $fname ) {
 184+ $message = "A database error has occurred\n" .
 185+ "Query: $sql\n" .
 186+ "Function: $fname\n" .
 187+ "Error: $errno $error\n";
 188+
 189+ parent::__construct( $db, $message );
 190+ $this->error = $error;
 191+ $this->errno = $errno;
 192+ $this->sql = $sql;
 193+ $this->fname = $fname;
 194+ }
 195+
 196+ function getText() {
 197+ if ( $this->useMessageCache() ) {
 198+ return wfMsg( 'dberrortextcl', htmlspecialchars( $this->getSQL() ),
 199+ htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) ) . "\n";
 200+ } else {
 201+ return $this->getMessage();
 202+ }
 203+ }
 204+
 205+ function getSQL() {
 206+ global $wgShowSQLErrors;
 207+ if( !$wgShowSQLErrors ) {
 208+ return $this->msg( 'sqlhidden', 'SQL hidden' );
 209+ } else {
 210+ return $this->sql;
 211+ }
 212+ }
 213+
 214+ function getPageTitle() {
 215+ return $this->msg( 'databaseerror', 'Database error' );
 216+ }
 217+
 218+ function getHTML() {
 219+ if ( $this->useMessageCache() ) {
 220+ return wfMsgNoDB( 'dberrortext', htmlspecialchars( $this->getSQL() ),
 221+ htmlspecialchars( $this->fname ), $this->errno, htmlspecialchars( $this->error ) );
 222+ } else {
 223+ return nl2br( htmlspecialchars( $this->getMessage() ) );
 224+ }
 225+ }
 226+}
 227+
 228+class DBUnexpectedError extends DBError {}
 229+
 230+/******************************************************************************/
 231+
 232+/**
45233 * Database abstraction object
46234 * @package MediaWiki
47235 */
@@ -49,22 +237,19 @@
50238 #------------------------------------------------------------------------------
51239 # Variables
52240 #------------------------------------------------------------------------------
53 - /**#@+
54 - * @private
55 - */
56 - var $mLastQuery = '';
57241
58 - var $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
59 - var $mOut, $mOpened = false;
 242+ protected $mLastQuery = '';
60243
61 - var $mFailFunction;
62 - var $mTablePrefix;
63 - var $mFlags;
64 - var $mTrxLevel = 0;
65 - var $mErrorCount = 0;
66 - var $mLBInfo = array();
67 - /**#@-*/
 244+ protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
 245+ protected $mOut, $mOpened = false;
68246
 247+ protected $mFailFunction;
 248+ protected $mTablePrefix;
 249+ protected $mFlags;
 250+ protected $mTrxLevel = 0;
 251+ protected $mErrorCount = 0;
 252+ protected $mLBInfo = array();
 253+
69254 #------------------------------------------------------------------------------
70255 # Accessors
71256 #------------------------------------------------------------------------------
@@ -173,6 +358,13 @@
174359 return !!($this->mFlags & $flag);
175360 }
176361
 362+ /**
 363+ * General read-only accessor
 364+ */
 365+ function getProperty( $name ) {
 366+ return $this->$name;
 367+ }
 368+
177369 #------------------------------------------------------------------------------
178370 # Other functions
179371 #------------------------------------------------------------------------------
@@ -189,7 +381,7 @@
190382 * @param $flags
191383 * @param $tablePrefix String: database table prefixes. By default use the prefix gave in LocalSettings.php
192384 */
193 - function Database( $server = false, $user = false, $password = false, $dbName = false,
 385+ function __construct( $server = false, $user = false, $password = false, $dbName = false,
194386 $failFunction = false, $flags = 0, $tablePrefix = 'get from global' ) {
195387
196388 global $wgOut, $wgDBprefix, $wgCommandLineMode;
@@ -234,7 +426,7 @@
235427 * @param failFunction
236428 * @param $flags
237429 */
238 - function newFromParams( $server, $user, $password, $dbName,
 430+ static function newFromParams( $server, $user, $password, $dbName,
239431 $failFunction = false, $flags = 0 )
240432 {
241433 return new Database( $server, $user, $password, $dbName, $failFunction, $flags );
@@ -253,9 +445,10 @@
254446 @dl('mysql.so');
255447 }
256448
 449+ # Fail now
257450 # Otherwise we get a suppressed fatal error, which is very hard to track down
258451 if ( !function_exists( 'mysql_connect' ) ) {
259 - wfDie( "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
 452+ throw new DBConnectionError( $this, "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
260453 }
261454
262455 $this->close();
@@ -328,7 +521,6 @@
329522 }
330523
331524 /**
332 - * @private
333525 * @param string $error fallback error message, used if none is given by MySQL
334526 */
335527 function reportConnectionError( $error = 'Unknown error' ) {
@@ -338,12 +530,15 @@
339531 }
340532
341533 if ( $this->mFailFunction ) {
 534+ # Legacy error handling method
342535 if ( !is_int( $this->mFailFunction ) ) {
343536 $ff = $this->mFailFunction;
344537 $ff( $this, $error );
345538 }
346539 } else {
347 - wfEmergencyAbort( $this, $error );
 540+ # New method
 541+ wfLogDBError( "Connection error: $error\n" );
 542+ throw new DBConnectionError( $this, $error );
348543 }
349544 }
350545
@@ -447,29 +642,13 @@
448643
449644 if( $ignore || $tempIgnore ) {
450645 wfDebug("SQL ERROR (ignored): $error\n");
 646+ $this->ignoreErrors( $ignore );
451647 } else {
452648 $sql1line = str_replace( "\n", "\\n", $sql );
453649 wfLogDBError("$fname\t{$this->mServer}\t$errno\t$error\t$sql1line\n");
454650 wfDebug("SQL ERROR: " . $error . "\n");
455 - if ( $wgCommandLineMode || !$this->mOut || empty( $wgFullyInitialised ) ) {
456 - $message = "A database error has occurred\n" .
457 - "Query: $sql\n" .
458 - "Function: $fname\n" .
459 - "Error: $errno $error\n";
460 - if ( !$wgCommandLineMode ) {
461 - $message = nl2br( $message );
462 - }
463 - if( $wgCommandLineMode && $wgColorErrors && !wfIsWindows() && posix_isatty(1) ) {
464 - $color = 31; // bright red!
465 - $message = "\x1b[1;{$color}m{$message}\x1b[0m";
466 - }
467 - wfDebugDieBacktrace( $message );
468 - } else {
469 - // this calls wfAbruptExit()
470 - $this->mOut->databaseError( $fname, $sql, $error, $errno );
471 - }
 651+ throw new DBQueryError( $this, $error, $errno, $sql, $fname );
472652 }
473 - $this->ignoreErrors( $ignore );
474653 }
475654
476655
@@ -561,9 +740,9 @@
562741 case '!': return $arg;
563742 case '&':
564743 # return $this->addQuotes( file_get_contents( $arg ) );
565 - wfDebugDieBacktrace( '& mode is not implemented. If it\'s really needed, uncomment the line above.' );
 744+ throw new DBUnexpectedError( $this, '& mode is not implemented. If it\'s really needed, uncomment the line above.' );
566745 default:
567 - wfDebugDieBacktrace( 'Received invalid match. This should never happen!' );
 746+ throw new DBUnexpectedError( $this, 'Received invalid match. This should never happen!' );
568747 }
569748 }
570749
@@ -575,7 +754,7 @@
576755 */
577756 function freeResult( $res ) {
578757 if ( !@/**/mysql_free_result( $res ) ) {
579 - wfDebugDieBacktrace( "Unable to free MySQL result\n" );
 758+ throw new DBUnexpectedError( $this, "Unable to free MySQL result" );
580759 }
581760 }
582761
@@ -585,7 +764,7 @@
586765 function fetchObject( $res ) {
587766 @/**/$row = mysql_fetch_object( $res );
588767 if( mysql_errno() ) {
589 - wfDebugDieBacktrace( 'Error in fetchObject(): ' . htmlspecialchars( mysql_error() ) );
 768+ throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' . htmlspecialchars( mysql_error() ) );
590769 }
591770 return $row;
592771 }
@@ -597,7 +776,7 @@
598777 function fetchRow( $res ) {
599778 @/**/$row = mysql_fetch_array( $res );
600779 if (mysql_errno() ) {
601 - wfDebugDieBacktrace( 'Error in fetchRow(): ' . htmlspecialchars( mysql_error() ) );
 780+ throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( mysql_error() ) );
602781 }
603782 return $row;
604783 }
@@ -608,7 +787,7 @@
609788 function numRows( $res ) {
610789 @/**/$n = mysql_num_rows( $res );
611790 if( mysql_errno() ) {
612 - wfDebugDieBacktrace( 'Error in numRows(): ' . htmlspecialchars( mysql_error() ) );
 791+ throw new DBUnexpectedError( $this, 'Error in numRows(): ' . htmlspecialchars( mysql_error() ) );
613792 }
614793 return $n;
615794 }
@@ -847,7 +1026,7 @@
8481027 * @param string $sql A SQL Query
8491028 * @static
8501029 */
851 - function generalizeSQL( $sql ) {
 1030+ static function generalizeSQL( $sql ) {
8521031 # This does the same as the regexp below would do, but in such a way
8531032 # as to avoid crashing php on some large strings.
8541033 # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql);
@@ -1079,7 +1258,7 @@
10801259 */
10811260 function makeList( $a, $mode = LIST_COMMA ) {
10821261 if ( !is_array( $a ) ) {
1083 - wfDebugDieBacktrace( 'Database::makeList called with incorrect parameters' );
 1262+ throw new DBUnexpectedError( $this, 'Database::makeList called with incorrect parameters' );
10841263 }
10851264
10861265 $first = true;
@@ -1282,7 +1461,7 @@
12831462 */
12841463 function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'Database::deleteJoin' ) {
12851464 if ( !$conds ) {
1286 - wfDebugDieBacktrace( 'Database::deleteJoin() called with empty $conds' );
 1465+ throw new DBUnexpectedError( $this, 'Database::deleteJoin() called with empty $conds' );
12871466 }
12881467
12891468 $delTable = $this->tableName( $delTable );
@@ -1327,7 +1506,7 @@
13281507 */
13291508 function delete( $table, $conds, $fname = 'Database::delete' ) {
13301509 if ( !$conds ) {
1331 - wfDebugDieBacktrace( 'Database::delete() called with no conditions' );
 1510+ throw new DBUnexpectedError( $this, 'Database::delete() called with no conditions' );
13321511 }
13331512 $table = $this->tableName( $table );
13341513 $sql = "DELETE FROM $table";
@@ -1379,7 +1558,7 @@
13801559 */
13811560 function limitResult($sql, $limit, $offset=false) {
13821561 if( !is_numeric($limit) ) {
1383 - wfDie( "Invalid non-numeric limit passed to limitResult()\n" );
 1562+ throw new DBUnexpectedError( $this, "Invalid non-numeric limit passed to limitResult()\n" );
13841563 }
13851564 return " $sql LIMIT "
13861565 . ( (is_numeric($offset) && $offset != 0) ? "{$offset}," : "" )
@@ -1737,7 +1916,7 @@
17381917 /**
17391918 * Replace variables in sourced SQL
17401919 */
1741 - function replaceVars( $ins ) {
 1920+ protected function replaceVars( $ins ) {
17421921 $varnames = array(
17431922 'wgDBserver', 'wgDBname', 'wgDBintlname', 'wgDBuser',
17441923 'wgDBpassword', 'wgDBsqluser', 'wgDBsqlpassword',
@@ -1764,7 +1943,7 @@
17651944 * Table name callback
17661945 * @private
17671946 */
1768 - function tableNameCallback( $matches ) {
 1947+ protected function tableNameCallback( $matches ) {
17691948 return $this->tableName( $matches[1] );
17701949 }
17711950

Follow-up revisions

RevisionCommit summaryAuthorDate
r71250Kill some crappy "failFunction" stuff, marked as old in r14625reedy13:38, 18 August 2010
r89821PostgreSQL install fixes:...tstarling11:32, 10 June 2011

Status & tagging log