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

Conversation

chrisdavidmills
Copy link
Contributor

Description

Chrome has updated its error reporting for IndexedDB large value read failures with transient causes such as low memory and unrecoverable causes such as source blob files being deleted.

Chrome 130 updates the DOMException types to be more appropriate, and Chrome 132 further updates them and improves the associated error messages. The data source is https://chromestatus.com/feature/5140210640486400.

In this PR, I have organized the different IDBRequest.error types into categories to hopefully make them easier to parse, and described and explained the large value read failure errors.

Motivation

Additional details

Related issues and pull requests

@chrisdavidmills chrisdavidmills requested a review from a team as a code owner December 1, 2024 16:20
@chrisdavidmills chrisdavidmills requested review from wbamberg and removed request for a team December 1, 2024 16:20
@github-actions github-actions bot added Content:WebAPI Web API docs size/m [PR only] 51-500 LoC changed labels Dec 1, 2024
@@ -14,22 +14,52 @@ request.

## 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 following error names can be returned

Choose a reason for hiding this comment

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

The phrasing "error names can be returned in the exception object" read a bit weird to me. How about "The exception object will have one of the following names, depending on what caused the error." ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, that reads much better. I've used your wording, in the next commit.


- `AbortError`
- : If you abort the transaction, then all requests still in progress receive this error.
- : Thrown if you abort the transaction, then all requests still in progress receive this error.

Choose a reason for hiding this comment

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

The asynchronous errors like this are not "thrown" in the sense that you can't try/catch them from script. So I would avoid that phrasing here and below.

From a script perspective, an error event is fired at the IDBRequest; if the developer has assigned an event handler, then the handler can inspect the request's error property and specifically error.name to see what the cause was.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills Dec 3, 2024

Choose a reason for hiding this comment

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

Right, OK, that makes sense. I've added a bit of text that comments on how these errors can be handled, based on your text above. Let me know if you think that approach makes sense.

I've also improved the code example snippet on the page so that the event handler logs the error name and message, rather than just the error object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've also removed the "thrown" language in each case.

- `ReadOnlyError`
- : Thrown if the mutating operation was attempted in a read-only transaction.
- `SyntaxError`
- : Thrown in the `keyPath` argument contains an invalid key path.

Choose a reason for hiding this comment

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

Typo: "in" should be "if".

But more importantly, SyntaxError is thrown synchronously when certain methods are called. It would never appear as a request's error. So this is not useful for this page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Duh, yeah, sorry. I should have clocked this. I wrote most of the original IndexedDB MDN docs but have not looked at them for years! TBH, they could really use an overhaul, but that is beyond the scope of this PR.

For now, I've removed the errors that shouldn't be listed here, gone through the spec to see what methods they are thrown on, and ensured they are included in their ref pages' "Exceptions" sections.

- : Thrown if the mutating operation was attempted in a read-only transaction.
- `SyntaxError`
- : Thrown in the `keyPath` argument contains an invalid key path.
- `TransactionInactiveError`

Choose a reason for hiding this comment

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

TransactionInactiveError is thrown synchronously when certain methods are called. It would never appear as a request's error. So this is not useful for this page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As before, I've removed it from this page and made sure that it is covered on the relevant method/property pages.


- `AbortError`
- : If you abort the transaction, then all requests still in progress receive this error.
- : Thrown if you abort the transaction, then all requests still in progress receive this error.
- `ReadOnlyError`

Choose a reason for hiding this comment

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

ReadOnlyError is thrown synchronously when certain methods are called. It would never appear as a request's error. So this is not useful for this page.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As before, I've removed it from this page and made sure that it is covered on the relevant method/property pages.

- : Thrown if the data being stored could not be cloned by the internal structured cloning algorithm.
- `InvalidAccessError`
- : Thrown if an invalid operation was performed on an object.
- `InvalidStateError`

Choose a reason for hiding this comment

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

InvalidStateError is thrown synchronously when certain methods are called. It would never appear as a request's error. So this is not useful for this page.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills Dec 3, 2024

Choose a reason for hiding this comment

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

As before, I've removed it from this section and made sure that it is covered on the relevant method/property pages.

In this case, an InvalidStateError is thrown when you try to access the actual error property before the request is complete. So I've mentioned that on this page.

- `UnknownError`
- : If the operation failed for reasons unrelated to the database itself.
A failure due to disk IO errors is such an example.
- : Thrown if you run out of disk quota and the user declined to grant the application more space.

Choose a reason for hiding this comment

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

Some browsers prompt the user; others use heuristics. So this could be softened a bit.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills Dec 3, 2024

Choose a reason for hiding this comment

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

I've updated it to:

Thrown 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.

Does that work for you?

- `VersionError`
- : If you try to open a database with a version lower than the one it already has.
- : Thrown if you try to open a database with a version lower than the one it already has.

Choose a reason for hiding this comment

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

Per above, not "thrown" but returned via the request's error property.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills Dec 3, 2024

Choose a reason for hiding this comment

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

As before, I've removed the "thrown" wording.

- `DataError` or `UnknownError`
- : Thrown for transient errors, including general disk IO errors.

### Related errors

In addition to the error codes sent to the {{ domxref("IDBRequest") }} object,

Choose a reason for hiding this comment

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

Not new, but this doesn't make much sense in this context.

"In addition to the error codes sent to the IDBRequest object..." - so far so good, that's what this page is about

"... asynchronous operations can also ..." - that doesn't make sense. This whole page is about how asynchronous operations that occur when the request is being executed, so this is like saying "In addition to A, there's also A".

Finally "...raise exceptions." - as noted, async operations can't raise exceptions, they fire error events.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, totally agree. I think I can just remove this section. This page is about async errors related to requests; there is no need to highlight that other errors occur in other places.


### Large value read failure errors

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. This category of errors can occur due to transient causes such as low memory and unrecoverable causes such as source blob files being deleted. Separate blob files containing IndexedDB data can end up being deleted because they show up as opaque files to users when they are using disk space recovery programs.

Choose a reason for hiding this comment

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

This is all a Chromium implementation detail, so doesn't really belong in MDN like this. Different browsers could (and do) approach storing large values very differently.

This page should lead with the error types (below), explain the cause (maybe mentioning that implementations can store values in different ways) and how developers should reason about what to do (e.g. retry if recovery is possible, wipe the database, etc)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Entirely agree. I've rephased/restructured it as suggested, and indicated that the storage description is just an example, which is the way Chrome does it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:WebAPI Web API docs size/m [PR only] 51-500 LoC changed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants