electric-sql / electric

Sync little subsets of your Postgres data into local apps and services.
https://electric-sql.com
Apache License 2.0
6.2k stars 146 forks source link

Server to client error messages #1406

Closed robacourt closed 3 months ago

robacourt commented 3 months ago

https://linear.app/electric-sql/issue/VAX-1983/improve-error-reporting-from-server-to-client

This PR add the ability of the client to show friendly error messages when the error has originated on the server.

For example:

an error occurred in satellite: INVALID_REQUEST Unexpected value for int2 column: 32769

At this stage I've not tried to hide any noise such as the stack trace in these scenarios. So the user in fact sees all of this:

an error occurred in satellite: INVALID_REQUEST Unexpected value for int2 column: 32769
Client can't connect with the server after a fatal error. This can happen due to divergence between local client and server. Use developer tools to clear the local database, or delete the database file. We're working on tools to allow recovering the state of the local database.
/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/error.js:35
  return new SatelliteError(
         ^

SatelliteError: Fatal error: Unexpected value for int2 column: 32769. Check log for more information
    at wrapFatalError (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/error.js:35:10)
    at SatelliteProcess._handleOrThrowClientError (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/process.js:542:13)
    at SatelliteProcess._handleClientError (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/process.js:525:10)
    at <anonymous> (/Users/rob/src/electric-sql/electric/clients/typescript/dist/util/asyncEventEmitter.js:103:17)
    at Array.map (<anonymous>)
    at AsyncEventEmitter.processQueue (/Users/rob/src/electric-sql/electric/clients/typescript/dist/util/asyncEventEmitter.js:101:32)
    at AsyncEventEmitter.enqueueEmit (/Users/rob/src/electric-sql/electric/clients/typescript/dist/util/asyncEventEmitter.js:129:12)
    at SatelliteClient.handleError (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/client.js:725:18)
    at Object.SatErrorResp (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/client.js:98:37)
    at SatelliteClient.handleIncoming (/Users/rob/src/electric-sql/electric/clients/typescript/dist/satellite/client.js:801:47) {
  code: 12
}

I've also added friendly error message generation on the server for data validation errors as an example of how you would implement the friendly error messages. Once the permissions system has been added, rejected writes could also generate a friendly error message in a similar way.

The client will now also see error messages that were already being set in the SatErrorResp such as:

kevin-dp commented 3 months ago

Minor comment but i think the error that is displayed on the client should make very clear that this is a server-side error, otherwise it will confuse people and they will think there is a problem with the client.

robacourt commented 3 months ago

Minor comment but i think the error that is displayed on the client should make very clear that this is a server-side error, otherwise it will confuse people and they will think there is a problem with the client.

The error message is now:

an error occurred in satellite: INVALID_REQUEST Server error: Unexpected value for int2 column: 32769

Hope that's clean enough @kevin-dp ?