| // Copyright 2011 The Closure Library Authors. All Rights Reserved. |
| // |
| // 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. |
| |
| /** |
| * @fileoverview Error classes for the IndexedDB wrapper. |
| * |
| */ |
| |
| |
| goog.provide('goog.db.Error'); |
| goog.provide('goog.db.Error.ErrorCode'); |
| goog.provide('goog.db.Error.ErrorName'); |
| goog.provide('goog.db.Error.VersionChangeBlockedError'); |
| |
| goog.require('goog.debug.Error'); |
| |
| |
| |
| /** |
| * A database error. Since the stack trace can be unhelpful in an asynchronous |
| * context, the error provides a message about where it was produced. |
| * |
| * @param {number|!DOMError} error The DOMError instance returned by the |
| * browser for Chrome22+, or an error code for previous versions. |
| * @param {string} context A description of where the error occured. |
| * @param {string=} opt_message Additional message. |
| * @constructor |
| * @extends {goog.debug.Error} |
| * @final |
| */ |
| goog.db.Error = function(error, context, opt_message) { |
| var errorCode = null; |
| var internalError = null; |
| if (goog.isNumber(error)) { |
| errorCode = error; |
| internalError = {name: goog.db.Error.getName(errorCode)}; |
| } else { |
| internalError = error; |
| errorCode = goog.db.Error.getCode(error.name); |
| } |
| |
| /** |
| * The code for this error. |
| * |
| * @type {number} |
| */ |
| this.code = errorCode; |
| |
| /** |
| * The DOMException as returned by the browser. |
| * |
| * @type {!DOMError} |
| * @private |
| */ |
| this.error_ = /** @type {!DOMError} */ (internalError); |
| |
| var msg = 'Error ' + context + ': ' + this.getName(); |
| if (opt_message) { |
| msg += ', ' + opt_message; |
| } |
| goog.db.Error.base(this, 'constructor', msg); |
| }; |
| goog.inherits(goog.db.Error, goog.debug.Error); |
| |
| |
| /** |
| * @return {string} The name of the error. |
| */ |
| goog.db.Error.prototype.getName = function() { |
| return this.error_.name; |
| }; |
| |
| |
| |
| /** |
| * A specific kind of database error. If a Version Change is unable to proceed |
| * due to other open database connections, it will block and this error will be |
| * thrown. |
| * |
| * @constructor |
| * @extends {goog.debug.Error} |
| * @final |
| */ |
| goog.db.Error.VersionChangeBlockedError = function() { |
| goog.db.Error.VersionChangeBlockedError.base( |
| this, 'constructor', 'Version change blocked'); |
| }; |
| goog.inherits(goog.db.Error.VersionChangeBlockedError, goog.debug.Error); |
| |
| |
| /** |
| * Synthetic error codes for database errors, for use when IndexedDB |
| * support is not available. This numbering differs in practice |
| * from the browser implementations, but it is not meant to be reliable: |
| * this object merely ensures that goog.db.Error is loadable on platforms |
| * that do not support IndexedDB. |
| * |
| * @enum {number} |
| * @private |
| */ |
| goog.db.Error.DatabaseErrorCode_ = { |
| UNKNOWN_ERR: 1, |
| NON_TRANSIENT_ERR: 2, |
| NOT_FOUND_ERR: 3, |
| CONSTRAINT_ERR: 4, |
| DATA_ERR: 5, |
| NOT_ALLOWED_ERR: 6, |
| TRANSACTION_INACTIVE_ERR: 7, |
| ABORT_ERR: 8, |
| READ_ONLY_ERR: 9, |
| TRANSIENT_ERR: 10, |
| TIMEOUT_ERR: 11, |
| QUOTA_ERR: 12, |
| INVALID_ACCESS_ERR: 13, |
| INVALID_STATE_ERR: 14 |
| }; |
| |
| |
| /** |
| * Error codes for database errors. |
| * @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBDatabaseException |
| * |
| * @enum {number} |
| */ |
| goog.db.Error.ErrorCode = { |
| UNKNOWN_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).UNKNOWN_ERR, |
| NON_TRANSIENT_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).NON_TRANSIENT_ERR, |
| NOT_FOUND_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).NOT_FOUND_ERR, |
| CONSTRAINT_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).CONSTRAINT_ERR, |
| DATA_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).DATA_ERR, |
| NOT_ALLOWED_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).NOT_ALLOWED_ERR, |
| TRANSACTION_INACTIVE_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).TRANSACTION_INACTIVE_ERR, |
| ABORT_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).ABORT_ERR, |
| READ_ONLY_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).READ_ONLY_ERR, |
| TIMEOUT_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).TIMEOUT_ERR, |
| QUOTA_ERR: (goog.global.IDBDatabaseException || |
| goog.global.webkitIDBDatabaseException || |
| goog.db.Error.DatabaseErrorCode_).QUOTA_ERR, |
| INVALID_ACCESS_ERR: (goog.global.DOMException || |
| goog.db.Error.DatabaseErrorCode_).INVALID_ACCESS_ERR, |
| INVALID_STATE_ERR: (goog.global.DOMException || |
| goog.db.Error.DatabaseErrorCode_).INVALID_STATE_ERR |
| }; |
| |
| |
| /** |
| * Translates an error code into a more useful message. |
| * |
| * @param {number} code Error code. |
| * @return {string} A debug message. |
| */ |
| goog.db.Error.getMessage = function(code) { |
| switch (code) { |
| case goog.db.Error.ErrorCode.UNKNOWN_ERR: |
| return 'Unknown error'; |
| case goog.db.Error.ErrorCode.NON_TRANSIENT_ERR: |
| return 'Invalid operation'; |
| case goog.db.Error.ErrorCode.NOT_FOUND_ERR: |
| return 'Required database object not found'; |
| case goog.db.Error.ErrorCode.CONSTRAINT_ERR: |
| return 'Constraint unsatisfied'; |
| case goog.db.Error.ErrorCode.DATA_ERR: |
| return 'Invalid data'; |
| case goog.db.Error.ErrorCode.NOT_ALLOWED_ERR: |
| return 'Operation disallowed'; |
| case goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR: |
| return 'Transaction not active'; |
| case goog.db.Error.ErrorCode.ABORT_ERR: |
| return 'Request aborted'; |
| case goog.db.Error.ErrorCode.READ_ONLY_ERR: |
| return 'Modifying operation not allowed in a read-only transaction'; |
| case goog.db.Error.ErrorCode.TIMEOUT_ERR: |
| return 'Transaction timed out'; |
| case goog.db.Error.ErrorCode.QUOTA_ERR: |
| return 'Database storage space quota exceeded'; |
| case goog.db.Error.ErrorCode.INVALID_ACCESS_ERR: |
| return 'Invalid operation'; |
| case goog.db.Error.ErrorCode.INVALID_STATE_ERR: |
| return 'Invalid state'; |
| default: |
| return 'Unrecognized exception with code ' + code; |
| } |
| }; |
| |
| |
| /** |
| * Names of all possible errors as returned from the browser. |
| * @see http://www.w3.org/TR/IndexedDB/#exceptions |
| * @enum {string} |
| */ |
| goog.db.Error.ErrorName = { |
| ABORT_ERR: 'AbortError', |
| CONSTRAINT_ERR: 'ConstraintError', |
| DATA_CLONE_ERR: 'DataCloneError', |
| DATA_ERR: 'DataError', |
| INVALID_ACCESS_ERR: 'InvalidAccessError', |
| INVALID_STATE_ERR: 'InvalidStateError', |
| NOT_FOUND_ERR: 'NotFoundError', |
| QUOTA_EXCEEDED_ERR: 'QuotaExceededError', |
| READ_ONLY_ERR: 'ReadOnlyError', |
| SYNTAX_ERROR: 'SyntaxError', |
| TIMEOUT_ERR: 'TimeoutError', |
| TRANSACTION_INACTIVE_ERR: 'TransactionInactiveError', |
| UNKNOWN_ERR: 'UnknownError', |
| VERSION_ERR: 'VersionError' |
| }; |
| |
| |
| /** |
| * Translates an error name to an error code. This is purely kept for backwards |
| * compatibility with Chrome21. |
| * |
| * @param {string} name The name of the erorr. |
| * @return {number} The error code corresponding to the error. |
| */ |
| goog.db.Error.getCode = function(name) { |
| switch (name) { |
| case goog.db.Error.ErrorName.UNKNOWN_ERR: |
| return goog.db.Error.ErrorCode.UNKNOWN_ERR; |
| case goog.db.Error.ErrorName.NOT_FOUND_ERR: |
| return goog.db.Error.ErrorCode.NOT_FOUND_ERR; |
| case goog.db.Error.ErrorName.CONSTRAINT_ERR: |
| return goog.db.Error.ErrorCode.CONSTRAINT_ERR; |
| case goog.db.Error.ErrorName.DATA_ERR: |
| return goog.db.Error.ErrorCode.DATA_ERR; |
| case goog.db.Error.ErrorName.TRANSACTION_INACTIVE_ERR: |
| return goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR; |
| case goog.db.Error.ErrorName.ABORT_ERR: |
| return goog.db.Error.ErrorCode.ABORT_ERR; |
| case goog.db.Error.ErrorName.READ_ONLY_ERR: |
| return goog.db.Error.ErrorCode.READ_ONLY_ERR; |
| case goog.db.Error.ErrorName.TIMEOUT_ERR: |
| return goog.db.Error.ErrorCode.TIMEOUT_ERR; |
| case goog.db.Error.ErrorName.QUOTA_EXCEEDED_ERR: |
| return goog.db.Error.ErrorCode.QUOTA_ERR; |
| case goog.db.Error.ErrorName.INVALID_ACCESS_ERR: |
| return goog.db.Error.ErrorCode.INVALID_ACCESS_ERR; |
| case goog.db.Error.ErrorName.INVALID_STATE_ERR: |
| return goog.db.Error.ErrorCode.INVALID_STATE_ERR; |
| default: |
| return goog.db.Error.ErrorCode.UNKNOWN_ERR; |
| } |
| }; |
| |
| |
| /** |
| * Converts an error code used by the old spec, to an error name used by the |
| * latest spec. |
| * @see http://www.w3.org/TR/IndexedDB/#exceptions |
| * |
| * @param {!goog.db.Error.ErrorCode|number} code The error code to convert. |
| * @return {!goog.db.Error.ErrorName} The corresponding name of the error. |
| */ |
| goog.db.Error.getName = function(code) { |
| switch (code) { |
| case goog.db.Error.ErrorCode.UNKNOWN_ERR: |
| return goog.db.Error.ErrorName.UNKNOWN_ERR; |
| case goog.db.Error.ErrorCode.NOT_FOUND_ERR: |
| return goog.db.Error.ErrorName.NOT_FOUND_ERR; |
| case goog.db.Error.ErrorCode.CONSTRAINT_ERR: |
| return goog.db.Error.ErrorName.CONSTRAINT_ERR; |
| case goog.db.Error.ErrorCode.DATA_ERR: |
| return goog.db.Error.ErrorName.DATA_ERR; |
| case goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR: |
| return goog.db.Error.ErrorName.TRANSACTION_INACTIVE_ERR; |
| case goog.db.Error.ErrorCode.ABORT_ERR: |
| return goog.db.Error.ErrorName.ABORT_ERR; |
| case goog.db.Error.ErrorCode.READ_ONLY_ERR: |
| return goog.db.Error.ErrorName.READ_ONLY_ERR; |
| case goog.db.Error.ErrorCode.TIMEOUT_ERR: |
| return goog.db.Error.ErrorName.TIMEOUT_ERR; |
| case goog.db.Error.ErrorCode.QUOTA_ERR: |
| return goog.db.Error.ErrorName.QUOTA_EXCEEDED_ERR; |
| case goog.db.Error.ErrorCode.INVALID_ACCESS_ERR: |
| return goog.db.Error.ErrorName.INVALID_ACCESS_ERR; |
| case goog.db.Error.ErrorCode.INVALID_STATE_ERR: |
| return goog.db.Error.ErrorName.INVALID_STATE_ERR; |
| default: |
| return goog.db.Error.ErrorName.UNKNOWN_ERR; |
| } |
| }; |
| |
| |
| /** |
| * Constructs an goog.db.Error instance from an IDBRequest. This abstraction is |
| * necessary to provide backwards compatibility with Chrome21. |
| * |
| * @param {!IDBRequest} request The request that failed. |
| * @param {string} message The error message to add to err if it's wrapped. |
| * @return {!goog.db.Error} The error that caused the failure. |
| */ |
| goog.db.Error.fromRequest = function(request, message) { |
| if ('error' in request) { |
| // Chrome 21 and before. |
| return new goog.db.Error(request.error, message); |
| } else if ('name' in request) { |
| // Chrome 22+. |
| var errorName = goog.db.Error.getName(request.errorCode); |
| return new goog.db.Error( |
| /**@type {!DOMError} */ ({name: errorName}), message); |
| } else { |
| return new goog.db.Error(/** @type {!DOMError} */ ( |
| {name: goog.db.Error.ErrorName.UNKNOWN_ERR}), message); |
| } |
| }; |
| |
| |
| /** |
| * Constructs an goog.db.Error instance from an DOMException. This abstraction |
| * is necessary to provide backwards compatibility with Chrome21. |
| * |
| * @param {!IDBDatabaseException} ex The exception that was thrown. |
| * @param {string} message The error message to add to err if it's wrapped. |
| * @return {!goog.db.Error} The error that caused the failure. |
| * @suppress {invalidCasts} The cast from IDBDatabaseException to DOMError |
| * is invalid and will not compile. |
| */ |
| goog.db.Error.fromException = function(ex, message) { |
| if ('name' in ex) { |
| // Chrome 22+. |
| var errorMessage = message + ': ' + ex.message; |
| return new goog.db.Error(/** @type {!DOMError} */ (ex), errorMessage); |
| } else if ('code' in ex) { |
| // Chrome 21 and before. |
| var errorName = goog.db.Error.getName(ex.code); |
| var errorMessage = message + ': ' + ex.message; |
| return new goog.db.Error( |
| /** @type {!DOMError} */ ({name: errorName}), errorMessage); |
| } else { |
| return new goog.db.Error(/** @type {!DOMError} */ ( |
| {name: goog.db.Error.ErrorName.UNKNOWN_ERR}), message); |
| } |
| }; |