Skip to content

Commit

Permalink
📝
Browse files Browse the repository at this point in the history
  • Loading branch information
zbeyens committed Jun 27, 2023
1 parent 9204798 commit 33dcb68
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 30 deletions.
63 changes: 48 additions & 15 deletions .changeset/silver-experts-complain.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,67 @@
Breaking changes:

- Enhanced error handling by introducing **`undefined`** checks
- Added **`editor.onError`** function to handle errors in functions that depend on **`editor`**
- Introduced `editor.strict`. If `true` (default), `editor.onError` will throw errors like before (unchanged behavior). If `false`, it will push the errors in `editor.errors` (new behavior).
- Updated return types of several functions to include **`| undefined`**
- Updated return types of many methods to include **`| undefined`** (see below).

You can now filter errors by type:
**`editor.strict`**:

- `true` (default): keep throwing errors everywhere.
- `false` (experimental): push errors to `editor.errors` array and let the editor continue to operate.

This option has no effect if you override `editor.onError`.

**`editor.onError`**: This function is used to handle errors in methods that depend on the **`editor`**.

```tsx
// throw only for `shouldNormalize` case
// Definition
export type EditorError<T extends SlateErrorType = SlateErrorType> = {
key: string // Unique key: `<methodName>.<case>`
message: string // Contextual error description
error?: SlateError<T> // Underlying generic error
data?: unknown // Additional operation data
recovery?: unknown // Recovery value to return on error.
}

export type SlateError<T extends SlateErrorType = SlateErrorType> = {
type: T // Error type
message: string // Error description
}

export const onError = <T extends SlateErrorType>(
editor: Editor,
context: EditorError
): any => {
const { message, recovery } = context

if (editor.strict) throw new Error(message)
editor.errors.push(context)
return recovery
}

// Overriding example
editor.onError = error => {
// or send to Sentry
console.warn(error.message)

// throw only for `shouldNormalize` case
if (error.key === 'shouldNormalize') {
throw new Error(error.message)
}
}
```

If you want to adopt the new error-free behavior, set `editor.strict = false`, the default being `true`. Or you can just override `onError` to handle errors.

Here is the quickest **migration** using non-null assertion (estimating to a couple of minutes):
if (error.key === 'isEnd') {
// return false when the end point is not found
return false
}

Throw an error like before:
// ...

```tsx
editor.onError = error => {
throw new Error(error.message)
return error.recovery
}
```

Here is the list of APIs that now return `| undefined`. Find usages for each of these and insert a non-null assertion. For example: `Path.next(...)` to `Path.next(...)!`
Slate methods will return `editor.onError(error)` on query error, so you can control what is returned for each case.

**Migration:** here is the list of APIs that now return `| undefined`. Find usages for each of these and insert a non-null assertion. For example: `Path.next(...)` to `Path.next(...)!`

```tsx
Path.next
Expand Down
52 changes: 37 additions & 15 deletions docs/concepts/12-error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,55 @@ Error handling in Slate is designed to provide more control to users while maint

Remember to utilize these error handling mechanisms to tailor your error management based on your specific use case and requirements, ensuring a smoother and more stable experience for your users. For example, you may want to throw errors in development, but in production you would prefer to have non-blocking errors for your users.

To disable error throwing everywhere, either set `editor.strict = false` or override `onError` to handle errors.
## `editor.strict`

## `editor.onError`
- `true` (default): throw errors everywhere.
- `false` (experimental): push errors to `editor.errors` array and let the editor continue to operate.

The **`editor.onError`** function is used to handle errors in functions that depend on the **`editor`**.
This option has no effect if you override `editor.onError`.

To set custom error handling behavior for the editor, override the **`editor.onError`** function.
## `editor.onError`

To throw errors on invalid operations:
This function is used to handle errors in methods that depend on the **`editor`**.

```tsx
editor.onError = error => {
throw new Error(error.message)
}
```

You can also filter errors by type:
Overriding example:

```tsx
// throw only for `shouldNormalize` case
editor.onError = error => {
// or send to Sentry
console.warn(error.message)

// throw only for `shouldNormalize` case
if (error.key === 'shouldNormalize') {
throw new Error(error.message)
}

if (error.key === 'isEnd') {
// return false when the end point is not found
return false
}

// ...

return error.recovery
}
```

## `editor.errors`
Slate methods will return `editor.onError(error)` on query error, so you can control what is returned for each case.

## `EditorError`

By default, Slate pushes errors to the `editor.errors` arrays. You can actively manage this array to keep it empty by implementing your own error handling strategies. This allows you to effectively monitor and address errors that occur during the editor's operation, contributing to a stable user experience.
```ts
export type EditorError<T extends SlateErrorType = SlateErrorType> = {
key: string // Unique key: `<methodName>.<case>`
message: string // Contextual error description
error?: SlateError<T> // Underlying generic error
data?: unknown // Additional operation data
recovery?: unknown // Recovery value to return on error.
}

export type SlateError<T extends SlateErrorType = SlateErrorType> = {
type: T // Error type
message: string // Error description
}
```

0 comments on commit 33dcb68

Please sign in to comment.