diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 6f30097f1e..dc1c2549ff 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -77,6 +77,7 @@ phutil_register_library_map(array( 'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing', 'AphrontQueryParameterException' => 'storage/exception/parameter', 'AphrontQueryRecoverableException' => 'storage/exception/recoverable', + 'AphrontQuerySchemaException' => 'storage/exception/schema', 'AphrontRedirectException' => 'aphront/exception/redirect', 'AphrontRedirectResponse' => 'aphront/response/redirect', 'AphrontReloadResponse' => 'aphront/response/reload', @@ -961,6 +962,7 @@ phutil_register_library_map(array( 'AphrontQueryObjectMissingException' => 'AphrontQueryException', 'AphrontQueryParameterException' => 'AphrontQueryException', 'AphrontQueryRecoverableException' => 'AphrontQueryException', + 'AphrontQuerySchemaException' => 'AphrontQueryException', 'AphrontRedirectException' => 'AphrontException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontReloadResponse' => 'AphrontRedirectResponse', diff --git a/src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php b/src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php index 311d935252..b9adc7a7a9 100644 --- a/src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php +++ b/src/storage/connection/mysql/AphrontMySQLDatabaseConnection.php @@ -293,27 +293,32 @@ class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection { $error = mysql_error($connection); } + $exmsg = "#{$errno}: {$error}"; + switch ($errno) { case 2013: // Connection Dropped case 2006: // Gone Away - throw new AphrontQueryConnectionLostException("#{$errno}: {$error}"); + throw new AphrontQueryConnectionLostException($exmsg); case 1213: // Deadlock case 1205: // Lock wait timeout exceeded - throw new AphrontQueryRecoverableException("#{$errno}: {$error}"); + throw new AphrontQueryRecoverableException($exmsg); case 1062: // Duplicate Key // NOTE: In some versions of MySQL we get a key name back here, but // older versions just give us a key index ("key 2") so it's not // portable to parse the key out of the error and attach it to the // exception. - throw new AphrontQueryDuplicateKeyException("{$errno}: {$error}"); + throw new AphrontQueryDuplicateKeyException($exmsg); case 1044: // Access denied to database case 1045: // Access denied (auth) case 1142: // Access denied to table case 1143: // Access denied to column - throw new AphrontQueryAccessDeniedException("#{$errno}: {$error}"); + throw new AphrontQueryAccessDeniedException($exmsg); + case 1146: // No such table + case 1154: // Unknown column "..." in field list + throw new AphrontQuerySchemaException($exmsg); default: // TODO: 1064 is syntax error, and quite terrible in production. - throw new AphrontQueryException("#{$errno}: {$error}"); + throw new AphrontQueryException($exmsg); } } diff --git a/src/storage/connection/mysql/__init__.php b/src/storage/connection/mysql/__init__.php index 4fbd82949e..c48b675987 100644 --- a/src/storage/connection/mysql/__init__.php +++ b/src/storage/connection/mysql/__init__.php @@ -15,6 +15,7 @@ phutil_require_module('phabricator', 'storage/exception/connection'); phutil_require_module('phabricator', 'storage/exception/connectionlost'); phutil_require_module('phabricator', 'storage/exception/duplicatekey'); phutil_require_module('phabricator', 'storage/exception/recoverable'); +phutil_require_module('phabricator', 'storage/exception/schema'); phutil_require_module('phutil', 'error'); phutil_require_module('phutil', 'serviceprofiler'); diff --git a/src/storage/exception/schema/AphrontQuerySchemaException.php b/src/storage/exception/schema/AphrontQuerySchemaException.php new file mode 100644 index 0000000000..a7cdd9f5d9 --- /dev/null +++ b/src/storage/exception/schema/AphrontQuerySchemaException.php @@ -0,0 +1,34 @@ +