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

[D1]: Error.cause be gone #9298

Merged
merged 3 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 content/d1/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ rss: file

# Changelog

## 2023-06-12

As of [`wrangler` v3.1.1`](https://github.com/cloudflare/workers-sdk/releases/tag/wrangler%403.1.1) the [D1 client API](/d1/platform/client-api/) now returns [detailed error messages](/d1/platform/client-api/#errors) within the top-level `Error.message` property, and no longer requires developers to inspect the `Error.cause.message` property.

In order to facilitate a transition from the previous `Error.cause` behaviour, detailed error messages will continue to be populated within `Error.cause` as well as the top-level `Error` object until June 30th, 2023. Future versions of both `wrangler` and the D1 client API will no longer populate `Error.cause` after this date.
elithrar marked this conversation as resolved.
Show resolved Hide resolved
## 2023-05-19

### New experimental backend
Expand Down
48 changes: 32 additions & 16 deletions content/d1/platform/client-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ D1 automatically converts supported JavaScript (including TypeScript) types pass

## Return object

The methods `stmt.run()`, `stmt.all()` and `db.batch()` return an object that contains the results (if applicable), the success status, and a meta object with the internal duration of the operation in milliseconds.
The methods `stmt.run()`, `stmt.all()` and `db.batch()` return a typed `D1Result` object that contains the results (if applicable), the success status, and a meta object with the internal duration of the operation in milliseconds.

```js
{
Expand All @@ -85,8 +85,19 @@ const { duration } = (await db.prepare('INSERT INTO users (name, age) VALUES (?1
console.log(duration); // 0.172
```

The `db.exec()` method returns a `D1ExecResult` object:

```js
{
count: number, // the number of queries executed
duration: number // duration of the operation in milliseconds
}
```

## Query statement methods

* The D1 API supports the following query statement methods:

* `await stmt.first( [column] )`
* `await stmt.all()`
* `await stmt.raw()`
Expand Down Expand Up @@ -205,7 +216,8 @@ return new Response(dump, {


### await db.exec()
Executes one or more queries directly without prepared statements or parameters binding. This method can have poorer performance (prepared statements can be reused in some cases) and, more importantly, is less safe. Only use this method for maintenance and one-shot tasks (example: migration jobs). The input can be one or multiple queries separated by \n.
Executes one or more queries directly without prepared statements or parameters binding. This method can have poorer performance (prepared statements can be reused in some cases) and, more importantly, is less safe. Only use this method for maintenance and one-shot tasks (example: migration jobs). The input can be one or multiple queries separated by `\n`.

If an error occurs, an exception is thrown with the query and error messages (see below for Errors), execution stops and further statements are not executed.

```js
Expand All @@ -220,8 +232,6 @@ console.log(out);
*/
```



## Reusing prepared statements
Prepared statements can be reused with new bindings:

Expand Down Expand Up @@ -370,35 +380,41 @@ console.log(r);
*/
```
## Errors

The `stmt.` and `db.` methods will throw a [Error object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) whenever an error occurs.

D1 Javascript Errors use [cause property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) for details.
{{<Aside type="note">}}

```js
new Error("D1_ERROR", { cause: new Error("Error detail") })
```
Prior to [`wrangler` 3.1.1](https://github.com/cloudflare/workers-sdk/releases/tag/wrangler%403.1.1), D1 JavaScript errors used the [cause property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) for detailed error messages.

To inspect these errors when using older versions of `wrangler`, you should log `error?.cause?.message`.

{{</Aside>}}

To capture exceptions, log the `Error.message` value. For example, a query with an invalid keyword - `INSERTZ` instead of `INSERT`:

To capture exceptions:
```js
try {
await db.exec("INSERTZ INTO my_table (name, employees) VALUES ()");
} catch (e: any) {
console.log({
message: e.message,
cause: e.cause.message,
console.error({
message: e.message
});
}
/*
```

... would throw the following error:

```json
{
"message": "D1_EXEC_ERROR",
"cause": "Error in line 1: INSERTZ INTO my_table (name, employees) VALUES (): sql error: near \"INSERTZ\": syntax error in INSERTZ INTO my_table (name, employees) VALUES () at offset 0"
"message": "D1_EXEC_ERROR: Error in line 1: INSERTZ INTO my_table (name, employees) VALUES (): sql error: near \"INSERTZ\": syntax error in INSERTZ INTO my_table (name, employees) VALUES () at offset 0"
}
*/
```

## Error list

D1 will return the following error constants, in addition to the extended (detailed) error message:

| Message | Cause |
| ---- | ---- |
| `D1_ERROR` | Generic error |
Expand Down