error.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. // Copyright 2011 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Error classes for the IndexedDB wrapper.
  16. *
  17. */
  18. goog.provide('goog.db.DomErrorLike');
  19. goog.provide('goog.db.Error');
  20. goog.provide('goog.db.Error.ErrorCode');
  21. goog.provide('goog.db.Error.ErrorName');
  22. goog.provide('goog.db.Error.VersionChangeBlockedError');
  23. goog.require('goog.asserts');
  24. goog.require('goog.debug.Error');
  25. /** @record */
  26. goog.db.DOMErrorLike = function() {};
  27. /** @type {string|undefined} */
  28. goog.db.DOMErrorLike.prototype.name;
  29. /**
  30. * A database error. Since the stack trace can be unhelpful in an asynchronous
  31. * context, the error provides a message about where it was produced.
  32. *
  33. * @param {number|!DOMError|!goog.db.DOMErrorLike} error The DOMError instance
  34. * returned by the browser for Chrome22+, or an error code for previous
  35. * versions.
  36. * @param {string} context A description of where the error occurred.
  37. * @param {string=} opt_message Additional message.
  38. * @constructor
  39. * @extends {goog.debug.Error}
  40. * @final
  41. */
  42. goog.db.Error = function(error, context, opt_message) {
  43. var errorCode = null;
  44. var internalError = null;
  45. if (goog.isNumber(error)) {
  46. errorCode = error;
  47. internalError = {name: goog.db.Error.getName(errorCode)};
  48. } else {
  49. internalError = error;
  50. errorCode = goog.db.Error.getCode(error.name);
  51. }
  52. /**
  53. * The code for this error.
  54. *
  55. * @type {number}
  56. */
  57. this.code = errorCode;
  58. /**
  59. * The DOMException as returned by the browser.
  60. *
  61. * @type {!goog.db.DOMErrorLike}
  62. * @private
  63. */
  64. this.error_ = internalError;
  65. var msg = 'Error ' + context + ': ' + this.getName();
  66. if (opt_message) {
  67. msg += ', ' + opt_message;
  68. }
  69. goog.db.Error.base(this, 'constructor', msg);
  70. };
  71. goog.inherits(goog.db.Error, goog.debug.Error);
  72. /**
  73. * @return {string} The name of the error.
  74. */
  75. goog.db.Error.prototype.getName = function() {
  76. return this.error_.name || '';
  77. };
  78. /**
  79. * A specific kind of database error. If a Version Change is unable to proceed
  80. * due to other open database connections, it will block and this error will be
  81. * thrown.
  82. *
  83. * @constructor
  84. * @extends {goog.debug.Error}
  85. * @final
  86. */
  87. goog.db.Error.VersionChangeBlockedError = function() {
  88. goog.db.Error.VersionChangeBlockedError.base(
  89. this, 'constructor', 'Version change blocked');
  90. };
  91. goog.inherits(goog.db.Error.VersionChangeBlockedError, goog.debug.Error);
  92. /**
  93. * Synthetic error codes for database errors, for use when IndexedDB
  94. * support is not available. This numbering differs in practice
  95. * from the browser implementations, but it is not meant to be reliable:
  96. * this object merely ensures that goog.db.Error is loadable on platforms
  97. * that do not support IndexedDB.
  98. *
  99. * @enum {number}
  100. * @private
  101. */
  102. goog.db.Error.DatabaseErrorCode_ = {
  103. UNKNOWN_ERR: 1,
  104. NON_TRANSIENT_ERR: 2,
  105. NOT_FOUND_ERR: 3,
  106. CONSTRAINT_ERR: 4,
  107. DATA_ERR: 5,
  108. NOT_ALLOWED_ERR: 6,
  109. TRANSACTION_INACTIVE_ERR: 7,
  110. ABORT_ERR: 8,
  111. READ_ONLY_ERR: 9,
  112. TRANSIENT_ERR: 10,
  113. TIMEOUT_ERR: 11,
  114. QUOTA_ERR: 12,
  115. INVALID_ACCESS_ERR: 13,
  116. INVALID_STATE_ERR: 14
  117. };
  118. /**
  119. * Error codes for database errors.
  120. * @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBDatabaseException
  121. *
  122. * @enum {number}
  123. */
  124. goog.db.Error.ErrorCode = {
  125. UNKNOWN_ERR: (goog.global.IDBDatabaseException ||
  126. goog.global.webkitIDBDatabaseException ||
  127. goog.db.Error.DatabaseErrorCode_)
  128. .UNKNOWN_ERR,
  129. NON_TRANSIENT_ERR: (goog.global.IDBDatabaseException ||
  130. goog.global.webkitIDBDatabaseException ||
  131. goog.db.Error.DatabaseErrorCode_)
  132. .NON_TRANSIENT_ERR,
  133. NOT_FOUND_ERR: (goog.global.IDBDatabaseException ||
  134. goog.global.webkitIDBDatabaseException ||
  135. goog.db.Error.DatabaseErrorCode_)
  136. .NOT_FOUND_ERR,
  137. CONSTRAINT_ERR: (goog.global.IDBDatabaseException ||
  138. goog.global.webkitIDBDatabaseException ||
  139. goog.db.Error.DatabaseErrorCode_)
  140. .CONSTRAINT_ERR,
  141. DATA_ERR: (goog.global.IDBDatabaseException ||
  142. goog.global.webkitIDBDatabaseException ||
  143. goog.db.Error.DatabaseErrorCode_)
  144. .DATA_ERR,
  145. NOT_ALLOWED_ERR: (goog.global.IDBDatabaseException ||
  146. goog.global.webkitIDBDatabaseException ||
  147. goog.db.Error.DatabaseErrorCode_)
  148. .NOT_ALLOWED_ERR,
  149. TRANSACTION_INACTIVE_ERR: (goog.global.IDBDatabaseException ||
  150. goog.global.webkitIDBDatabaseException ||
  151. goog.db.Error.DatabaseErrorCode_)
  152. .TRANSACTION_INACTIVE_ERR,
  153. ABORT_ERR: (goog.global.IDBDatabaseException ||
  154. goog.global.webkitIDBDatabaseException ||
  155. goog.db.Error.DatabaseErrorCode_)
  156. .ABORT_ERR,
  157. READ_ONLY_ERR: (goog.global.IDBDatabaseException ||
  158. goog.global.webkitIDBDatabaseException ||
  159. goog.db.Error.DatabaseErrorCode_)
  160. .READ_ONLY_ERR,
  161. TIMEOUT_ERR: (goog.global.IDBDatabaseException ||
  162. goog.global.webkitIDBDatabaseException ||
  163. goog.db.Error.DatabaseErrorCode_)
  164. .TIMEOUT_ERR,
  165. QUOTA_ERR: (goog.global.IDBDatabaseException ||
  166. goog.global.webkitIDBDatabaseException ||
  167. goog.db.Error.DatabaseErrorCode_)
  168. .QUOTA_ERR,
  169. INVALID_ACCESS_ERR:
  170. (goog.global.DOMException || goog.db.Error.DatabaseErrorCode_)
  171. .INVALID_ACCESS_ERR,
  172. INVALID_STATE_ERR:
  173. (goog.global.DOMException || goog.db.Error.DatabaseErrorCode_)
  174. .INVALID_STATE_ERR
  175. };
  176. /**
  177. * Translates an error code into a more useful message.
  178. *
  179. * @param {number} code Error code.
  180. * @return {string} A debug message.
  181. */
  182. goog.db.Error.getMessage = function(code) {
  183. switch (code) {
  184. case goog.db.Error.ErrorCode.UNKNOWN_ERR:
  185. return 'Unknown error';
  186. case goog.db.Error.ErrorCode.NON_TRANSIENT_ERR:
  187. return 'Invalid operation';
  188. case goog.db.Error.ErrorCode.NOT_FOUND_ERR:
  189. return 'Required database object not found';
  190. case goog.db.Error.ErrorCode.CONSTRAINT_ERR:
  191. return 'Constraint unsatisfied';
  192. case goog.db.Error.ErrorCode.DATA_ERR:
  193. return 'Invalid data';
  194. case goog.db.Error.ErrorCode.NOT_ALLOWED_ERR:
  195. return 'Operation disallowed';
  196. case goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR:
  197. return 'Transaction not active';
  198. case goog.db.Error.ErrorCode.ABORT_ERR:
  199. return 'Request aborted';
  200. case goog.db.Error.ErrorCode.READ_ONLY_ERR:
  201. return 'Modifying operation not allowed in a read-only transaction';
  202. case goog.db.Error.ErrorCode.TIMEOUT_ERR:
  203. return 'Transaction timed out';
  204. case goog.db.Error.ErrorCode.QUOTA_ERR:
  205. return 'Database storage space quota exceeded';
  206. case goog.db.Error.ErrorCode.INVALID_ACCESS_ERR:
  207. return 'Invalid operation';
  208. case goog.db.Error.ErrorCode.INVALID_STATE_ERR:
  209. return 'Invalid state';
  210. default:
  211. return 'Unrecognized exception with code ' + code;
  212. }
  213. };
  214. /**
  215. * Names of all possible errors as returned from the browser.
  216. * @see http://www.w3.org/TR/IndexedDB/#exceptions
  217. * @enum {string}
  218. */
  219. goog.db.Error.ErrorName = {
  220. ABORT_ERR: 'AbortError',
  221. CONSTRAINT_ERR: 'ConstraintError',
  222. DATA_CLONE_ERR: 'DataCloneError',
  223. DATA_ERR: 'DataError',
  224. INVALID_ACCESS_ERR: 'InvalidAccessError',
  225. INVALID_STATE_ERR: 'InvalidStateError',
  226. NOT_FOUND_ERR: 'NotFoundError',
  227. QUOTA_EXCEEDED_ERR: 'QuotaExceededError',
  228. READ_ONLY_ERR: 'ReadOnlyError',
  229. SYNTAX_ERROR: 'SyntaxError',
  230. TIMEOUT_ERR: 'TimeoutError',
  231. TRANSACTION_INACTIVE_ERR: 'TransactionInactiveError',
  232. UNKNOWN_ERR: 'UnknownError',
  233. VERSION_ERR: 'VersionError'
  234. };
  235. /**
  236. * Translates an error name to an error code. This is purely kept for backwards
  237. * compatibility with Chrome21.
  238. *
  239. * @param {string|undefined} name The name of the erorr.
  240. * @return {number} The error code corresponding to the error.
  241. */
  242. goog.db.Error.getCode = function(name) {
  243. switch (name) {
  244. case goog.db.Error.ErrorName.UNKNOWN_ERR:
  245. return goog.db.Error.ErrorCode.UNKNOWN_ERR;
  246. case goog.db.Error.ErrorName.NOT_FOUND_ERR:
  247. return goog.db.Error.ErrorCode.NOT_FOUND_ERR;
  248. case goog.db.Error.ErrorName.CONSTRAINT_ERR:
  249. return goog.db.Error.ErrorCode.CONSTRAINT_ERR;
  250. case goog.db.Error.ErrorName.DATA_ERR:
  251. return goog.db.Error.ErrorCode.DATA_ERR;
  252. case goog.db.Error.ErrorName.TRANSACTION_INACTIVE_ERR:
  253. return goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR;
  254. case goog.db.Error.ErrorName.ABORT_ERR:
  255. return goog.db.Error.ErrorCode.ABORT_ERR;
  256. case goog.db.Error.ErrorName.READ_ONLY_ERR:
  257. return goog.db.Error.ErrorCode.READ_ONLY_ERR;
  258. case goog.db.Error.ErrorName.TIMEOUT_ERR:
  259. return goog.db.Error.ErrorCode.TIMEOUT_ERR;
  260. case goog.db.Error.ErrorName.QUOTA_EXCEEDED_ERR:
  261. return goog.db.Error.ErrorCode.QUOTA_ERR;
  262. case goog.db.Error.ErrorName.INVALID_ACCESS_ERR:
  263. return goog.db.Error.ErrorCode.INVALID_ACCESS_ERR;
  264. case goog.db.Error.ErrorName.INVALID_STATE_ERR:
  265. return goog.db.Error.ErrorCode.INVALID_STATE_ERR;
  266. default:
  267. return goog.db.Error.ErrorCode.UNKNOWN_ERR;
  268. }
  269. };
  270. /**
  271. * Converts an error code used by the old spec, to an error name used by the
  272. * latest spec.
  273. * @see http://www.w3.org/TR/IndexedDB/#exceptions
  274. *
  275. * @param {!goog.db.Error.ErrorCode|number} code The error code to convert.
  276. * @return {!goog.db.Error.ErrorName} The corresponding name of the error.
  277. */
  278. goog.db.Error.getName = function(code) {
  279. switch (code) {
  280. case goog.db.Error.ErrorCode.UNKNOWN_ERR:
  281. return goog.db.Error.ErrorName.UNKNOWN_ERR;
  282. case goog.db.Error.ErrorCode.NOT_FOUND_ERR:
  283. return goog.db.Error.ErrorName.NOT_FOUND_ERR;
  284. case goog.db.Error.ErrorCode.CONSTRAINT_ERR:
  285. return goog.db.Error.ErrorName.CONSTRAINT_ERR;
  286. case goog.db.Error.ErrorCode.DATA_ERR:
  287. return goog.db.Error.ErrorName.DATA_ERR;
  288. case goog.db.Error.ErrorCode.TRANSACTION_INACTIVE_ERR:
  289. return goog.db.Error.ErrorName.TRANSACTION_INACTIVE_ERR;
  290. case goog.db.Error.ErrorCode.ABORT_ERR:
  291. return goog.db.Error.ErrorName.ABORT_ERR;
  292. case goog.db.Error.ErrorCode.READ_ONLY_ERR:
  293. return goog.db.Error.ErrorName.READ_ONLY_ERR;
  294. case goog.db.Error.ErrorCode.TIMEOUT_ERR:
  295. return goog.db.Error.ErrorName.TIMEOUT_ERR;
  296. case goog.db.Error.ErrorCode.QUOTA_ERR:
  297. return goog.db.Error.ErrorName.QUOTA_EXCEEDED_ERR;
  298. case goog.db.Error.ErrorCode.INVALID_ACCESS_ERR:
  299. return goog.db.Error.ErrorName.INVALID_ACCESS_ERR;
  300. case goog.db.Error.ErrorCode.INVALID_STATE_ERR:
  301. return goog.db.Error.ErrorName.INVALID_STATE_ERR;
  302. default:
  303. return goog.db.Error.ErrorName.UNKNOWN_ERR;
  304. }
  305. };
  306. /**
  307. * Constructs an goog.db.Error instance from an IDBRequest. This abstraction is
  308. * necessary to provide backwards compatibility with Chrome21.
  309. *
  310. * @param {!IDBRequest} request The request that failed.
  311. * @param {string} message The error message to add to err if it's wrapped.
  312. * @return {!goog.db.Error} The error that caused the failure.
  313. */
  314. goog.db.Error.fromRequest = function(request, message) {
  315. if ('error' in request) {
  316. // Chrome 22+
  317. return new goog.db.Error(goog.asserts.assert(request.error), message);
  318. } else {
  319. return new goog.db.Error(
  320. {name: goog.db.Error.ErrorName.UNKNOWN_ERR}, message);
  321. }
  322. };
  323. /**
  324. * Constructs an goog.db.Error instance from an DOMException. This abstraction
  325. * is necessary to provide backwards compatibility with Chrome21.
  326. *
  327. * @param {!DOMError|!DOMException} ex The exception that was thrown.
  328. * @param {string} message The error message to add to err if it's wrapped.
  329. * @return {!goog.db.Error} The error that caused the failure.
  330. */
  331. goog.db.Error.fromException = function(ex, message) {
  332. if ('name' in ex) {
  333. // Chrome 22+.
  334. var errorMessage = message + ': ' + ex.message;
  335. return new goog.db.Error(ex, errorMessage);
  336. } else if ('code' in ex) {
  337. // Chrome 21 and before.
  338. var errorName = goog.db.Error.getName(ex.code);
  339. var errorMessage = message + ': ' + ex.message;
  340. return new goog.db.Error({name: errorName}, errorMessage);
  341. } else {
  342. return new goog.db.Error(
  343. {name: goog.db.Error.ErrorName.UNKNOWN_ERR}, message);
  344. }
  345. };