Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for improved error reporting for IndexedDB large value read failures #37041

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions files/en-us/web/api/idbcursor/key/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ key can be any data type.

A value of any type.

### Exceptions

- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if the cursor is advancing or has finished.

## Examples

In this simple fragment we create a transaction, retrieve an object store, then use a
Expand Down
5 changes: 5 additions & 0 deletions files/en-us/web/api/idbcursor/primarykey/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ undefined. The cursor's primary key can be any data type.

A value of any data type.

### Exceptions

- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if the cursor is advancing or has finished.

## Examples

In this simple fragment we create a transaction, retrieve an object store, then use a
Expand Down
5 changes: 5 additions & 0 deletions files/en-us/web/api/idbcursor/request/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ The **`request`** read-only property of the {{domxref("IDBCursor")}} interface r

An {{domxref("IDBRequest")}} object instance.

### Exceptions

- `InvalidStateError` {{domxref("DOMException")}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request never throws

(key/primaryKey/value do while the cursor is advancing since it's in between positions, but request has a stable value for the lifetime of the IDBCursor so never throws)

- : Thrown if the cursor is already advancing.

## Examples

When you open a cursor, the `request` property is then available on that cursor object, to tell you what request object the cursor originated from. For example:
Expand Down
14 changes: 8 additions & 6 deletions files/en-us/web/api/idbdatabase/createobjectstore/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,22 @@ A new {{domxref("IDBObjectStore")}}.
This method may raise a {{domxref("DOMException")}} with a `name` of
one of the following types:

- `ConstraintError` {{domxref("DOMException")}}
- : Thrown if an object store with the given name (based on a case-sensitive comparison)
already exists in the connected database.
- `InvalidAccessError` {{domxref("DOMException")}}
- : Thrown if `autoIncrement` is set to true and `keyPath` is
either an empty string or an array containing an empty string.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be: "either an empty string or an array."

The array contents don't matter.

- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if the method was not called from a
`versionchange` transaction callback.
- `SyntaxError`
- : Thrown if the `keyPath` option contains an invalid key path.
- `TransactionInactiveError` {{domxref("DOMException")}}
- : Thrown if a request is made on a source database that does not exist

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also if the upgrade transaction has completed, or is processing a request.

(for example, when the database has been deleted or removed). In Firefox previous to version 41,
an `InvalidStateError` was raised in this case as well, which
was misleading; this has now been fixed (see [Firefox bug 1176165](https://bugzil.la/1176165)).
- `ConstraintError` {{domxref("DOMException")}}
- : Thrown if an object store with the given name (based on a case-sensitive comparison)
already exists in the connected database.
- `InvalidAccessError` {{domxref("DOMException")}}
- : Thrown if `autoIncrement` is set to true and `keyPath` is
either an empty string or an array containing an empty string.

## Examples

Expand Down
2 changes: 2 additions & 0 deletions files/en-us/web/api/idbobjectstore/clear/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ If the operation is successful, the value of the request's {{domxref("IDBRequest

### Exceptions

- `InvalidStateError` {{domxref("DOMException")}}
- : Thrown if the object store has been deleted.
- `ReadOnlyError` {{domxref("DOMException")}}
- : Thrown if the transaction associated with this operation is in read-only [mode](/en-US/docs/Web/API/IDBTransaction/mode).
- `TransactionInactiveError` {{domxref("DOMException")}}
Expand Down
41 changes: 24 additions & 17 deletions files/en-us/web/api/idbrequest/error/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,38 @@ browser-compat: api.IDBRequest.error

The **`error`** read-only property of the
{{domxref("IDBRequest")}} interface returns the error in the event of an unsuccessful
request.
request. If the request is not completed, the error is not available and an `InvalidStateError` exception is
thrown.

## Value

A {{domxref("DOMException")}} or `null` if there is no error. The following error names are returned
in the exception object:
A {{domxref("DOMException")}} or `null` if there is no error. The exception object will have one of the following names, depending on what caused the error.

These errors are asynchronous, meaning that they can't be handled via [`try...catch`](/en-US/docs/Web/JavaScript/Reference/Statements/try...catch). However, if an `IDBRequest` has an {{domxref("IDBRequest.error", "error")}} event handler assigned, you can still inspect such errors by querying the request's `error` property via the event object, for example [`event.target.error.name`](/en-US/docs/Web/API/DOMException/name) or [`event.target.error.message`](/en-US/docs/Web/API/DOMException/message).

- `AbortError`
- : If you abort the transaction, then all requests still in progress receive this error.
- `ConstraintError`
- : If you insert data that doesn't conform to a constraint.
It's an exception type for creating stores and indexes.
You get this error, for example, if you try to add a new key that already exists in the record.
- : Received if you insert data that doesn't conform to a constraint when creating stores and indexes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"when creating stores and indexes" may be misleading; when you're calling createObjectStore() or createIndex() those are synchronous ops that throw. You could reword this as "... doesn't conform to a constraint when populating stores."

For example, you will get this error if you try to add a new key that already exists in the record.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "store" not "record"

alternately: "a new key that already exists for a record in the store"

(a record is a key/value pair in a store)

- `DataError` or `UnknownError`
- : Received for transient read failure errors, including general disk IO errors. See "Large value read failure errors" below for more details.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "Large value read..." be a hyperlink to the section?

- `NotFoundError` or `NotReadableError`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the spec, we don't issue "NotFoundError" in this case.

https://github.com/w3c/IndexedDB/pull/430/files only added "NotReadableError" for this case.

But maybe I missed something?

- : Received for unrecoverable read failure errors. See "Large value read failure errors" below for more details.
- `QuotaExceededError`
- : If you run out of disk quota and the user declined to grant you more space.
- `UnknownError`
- : If the operation failed for reasons unrelated to the database itself.
A failure due to disk IO errors is such an example.
- : Received if the application runs out of disk quota. In some cases, browsers prompt the user for more space, and the error is received if they decline the request. In other cases, the browser uses heuristics to determine whether more space can be assigned.
- `VersionError`
- : If you try to open a database with a version lower than the one it already has.
- : If you try to open a database with a version lower than the one it already has, this error is received.

### Large value read failure errors

Large value read failure errors occur when an IndexedDB stores large blob values (for example, audio files for an offline podcast app), and then subsequently fails to read those values. This category of errors can occur due to transient causes such as low memory and unrecoverable causes such as source blob files being deleted.

Different IndexedDB implementations store large values in different ways. For example, in Chrome, large IndexedDB values are not stored directly in the underlying database; instead, they are stored as separate files that are accessed via a reference stored in the database. It has been observed that these separate files can end up being deleted because they show up as opaque files to users when they are using disk space recovery programs.

Possible corrective actions for such cases might include notifying the user, deleting the entry from the database, then attempting to re-fetch the data from the server.

In addition to the error codes sent to the {{ domxref("IDBRequest") }} object,
asynchronous operations can also raise exceptions. The list describes problems that
could occur when the request is being executed, but you might also encounter other
problems when the request is being made. For example, if the result is accessed
while the request is not completed, the `InvalidStateError` exception is thrown.
More recent browser versions have changed the error types and improved the error messages to help developers distinguish between transient and unrecoverable cases.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add: "Specifically, "NotReadableError" signals that the record is present in the database, but that the value could not be retrieved."


## Examples

Expand Down Expand Up @@ -78,7 +84,8 @@ objectStoreTitleRequest.onsuccess = () => {
objectStoreTitleRequest.onerror = () => {
// If an error occurs with the request, log what it is
console.log(
`There has been an error with retrieving your data: ${objectStoreTitleRequest.error}`,
`There has been an error with retrieving your data:
${objectStoreTitleRequest.error.name}: ${objectStoreTitleRequest.error.message}`,
);
};
```
Expand Down
Loading