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

fix: always throw errors & always use named Error classes #1985

Merged
merged 35 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
03a5082
fix: always throw errors
KyleAMathews Nov 16, 2024
81939ea
use named error classes and document
KyleAMathews Nov 16, 2024
9b1b8e2
Add changeset
KyleAMathews Nov 16, 2024
9135285
improve wording
KyleAMathews Nov 16, 2024
910b254
small fixes
KyleAMathews Nov 17, 2024
33ea0b0
Fix test
KyleAMathews Nov 17, 2024
91d06ba
fixes
KyleAMathews Nov 17, 2024
1ae70cf
also update name on FetchBackoffAbortError
KyleAMathews Nov 18, 2024
36afa6e
refactor(typescript-client): improve error handling
KyleAMathews Nov 18, 2024
ddc4c46
Update changeset
KyleAMathews Nov 18, 2024
c1650ed
fix stylechck
KyleAMathews Nov 18, 2024
6ceb2e0
options are readable
KyleAMathews Nov 18, 2024
3350125
add tsts
KyleAMathews Nov 18, 2024
fbb9ce1
fix test
KyleAMathews Nov 18, 2024
e269416
try fixing again
KyleAMathews Nov 18, 2024
1f39125
oops
KyleAMathews Nov 18, 2024
07bbfb9
unmount cleaner
KyleAMathews Nov 18, 2024
1f1bee7
Add onError option
kevin-dp Nov 19, 2024
e78a346
restore notifying subscribers of errors
KyleAMathews Nov 19, 2024
e28a76b
fixes
KyleAMathews Nov 19, 2024
f453569
fixes
KyleAMathews Nov 19, 2024
172452d
make shapestream.start private
KyleAMathews Nov 19, 2024
adb13ed
Fixes
KyleAMathews Nov 19, 2024
24359d2
Fix snapshot
KyleAMathews Nov 19, 2024
d736999
Fix test that checks missing headers by explicitly handling the error.
kevin-dp Nov 20, 2024
270a8ec
Fix handling of error in integration test.
kevin-dp Nov 20, 2024
701f947
Fix bug with handling of missing headers + fix test expectations
kevin-dp Nov 20, 2024
1d42a1a
Fix incorrect usage of expect in test
kevin-dp Nov 20, 2024
b12b6fb
Replace assertions by expectations
kevin-dp Nov 20, 2024
a1b6d38
Fix check for absence of a stream/shape error
kevin-dp Nov 20, 2024
b5e87f0
Remove obsolete FetchError type
kevin-dp Nov 21, 2024
f3b5fec
Removed autoStart mention from changeset
kevin-dp Nov 21, 2024
a690940
Fixes after rebase
kevin-dp Nov 21, 2024
35e24f0
Remove comments
kevin-dp Nov 21, 2024
7ecbfdb
feat! (ts client): Remove subscribeOnceToUpToDate from shape stream (…
kevin-dp Nov 21, 2024
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
15 changes: 15 additions & 0 deletions .changeset/fair-pants-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@electric-sql/client": patch
---

refactor: improve error handling with new error classes & stream control

- Add `onError` handler to ShapeStream for centralized error handling
- Add new error classes:
- MissingShapeUrlError
- InvalidSignalError
- MissingShapeHandleError
- ReservedParamError
- ParserNullValueError
- ShapeStreamAlreadyRunningError
- Improve error propagation through ShapeStream lifecycle
5 changes: 5 additions & 0 deletions .changeset/grumpy-cougars-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@electric-sql/client": minor
---

[BREAKING] Remove subscribeOnceToUpToDate method from ShapeStream. Instead, you should subscribe to the stream and check for the up-to-date control message.
7 changes: 2 additions & 5 deletions packages/react-hooks/src/react-hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function getShapeStream<T extends Row<unknown>>(
// If the stream is already cached, return it if valid
if (streamCache.has(shapeHash)) {
const stream = streamCache.get(shapeHash)! as ShapeStream<T>
if (stream.error === undefined && !stream.options.signal?.aborted) {
if (!stream.error && !stream.options.signal?.aborted) {
return stream
}

Expand All @@ -57,10 +57,7 @@ export function getShape<T extends Row<unknown>>(
): Shape<T> {
// If the stream is already cached, return it if valid
if (shapeCache.has(shapeStream)) {
if (
shapeStream.error === undefined &&
!shapeStream.options.signal?.aborted
) {
if (!shapeStream.error && !shapeStream.options.signal?.aborted) {
return shapeCache.get(shapeStream)! as Shape<T>
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-hooks/test/support/global-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default async function ({ provide }: GlobalSetupContext) {
provide(`proxyCachePath`, proxyCachePath)

return async () => {
await client.query(`DROP SCHEMA electric_test`)
await client.query(`DROP SCHEMA electric_test CASCADE`)
await client.end()
}
}
14 changes: 8 additions & 6 deletions packages/react-hooks/test/support/test-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ export const testWithDbClient = test.extend<{
clearShape: async ({}, use) => {
use(async (table: string, handle?: string) => {
const baseUrl = inject(`baseUrl`)
const resp = await fetch(
`${baseUrl}/v1/shape?table=${table}${handle ? `&handle=${handle}` : ``}`,
{
method: `DELETE`,
}
)
const url = new URL(`${baseUrl}/v1/shape`)
url.searchParams.set(`table`, table)
if (handle) {
url.searchParams.set(`handle`, handle)
}
const resp = await fetch(url.toString(), {
method: `DELETE`,
})
if (!resp.ok) {
console.error(
await FetchError.fromResponse(
Expand Down
46 changes: 45 additions & 1 deletion packages/typescript-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,51 @@ shape.subscribe(({ rows }) => {
}
```

See the [Docs](https://electric-sql.com) and [Examples](https://electric-sql.com/examples/basic) for more information.
### Error Handling

The ShapeStream provides two ways to handle errors:

1. Using the `onError` handler:
```typescript
const stream = new ShapeStream({
url: `${BASE_URL}/v1/shape`,
table: `foo`,
onError: (error) => {
// Handle all stream errors here
console.error('Stream error:', error)
}
})
```

If no `onError` handler is provided, the ShapeStream will throw errors that occur during streaming.

2. Individual subscribers can optionally handle errors specific to their subscription:
```typescript
stream.subscribe(
(messages) => {
// Handle messages
},
(error) => {
// Handle errors for this specific subscription
console.error('Subscription error:', error)
}
)
```

Common error types include:
- `MissingShapeUrlError`: Missing required URL parameter
- `InvalidSignalError`: Invalid AbortSignal instance
- `ReservedParamError`: Using reserved parameter names

Runtime errors:
- `FetchError`: HTTP errors during shape fetching
- `FetchBackoffAbortError`: Fetch aborted using AbortSignal
- `MissingShapeHandleError`: Missing required shape handle
- `ParserNullValueError`: Parser encountered NULL value in a column that doesn't allow NULL values

See the [typescript client docs on the website](https://electric-sql.com/docs/api/clients/typescript#error-handling) for more details on error handling.

And in general, see the [docs website](https://electric-sql.com) and [examples folder](https://electric-sql.com/examples/basic) for more information.

## Develop

Expand Down
Loading
Loading