From 46a914267613d60791dc96d6e82bc3db2cfd236c Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 27 Jun 2023 15:27:56 +0100 Subject: [PATCH 1/7] propagate errors coreectly for datasource plus --- .../src/integrations/microsoftSqlServer.ts | 15 ++++++++++++--- packages/server/src/integrations/mysql.ts | 17 +++++++++++++++-- packages/server/src/integrations/postgres.ts | 16 +++++++++++++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index 291aad8631..ee3cbc9970 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -10,6 +10,7 @@ import { DatasourcePlus, DatasourceFeature, ConnectionInfo, + SourceName, } from "@budibase/types" import { getSqlQuery, @@ -20,6 +21,7 @@ import { } from "./utils" import Sql from "./base/sql" import { MSSQLTablesResponse, MSSQLColumn } from "./base/types" +import { getReadableErrorMessage } from "./base/errorMapping" const sqlServer = require("mssql") const DEFAULT_SCHEMA = "dbo" @@ -177,9 +179,16 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;` : query.sql return await request.query(sql) - } catch (err) { - // @ts-ignore - throw new Error(err) + } catch (err: any) { + let readableMessage = getReadableErrorMessage( + SourceName.SQL_SERVER, + err.errno + ) + if (readableMessage) { + throw new Error(readableMessage) + } else { + throw new Error(err.message as string) + } } } diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index c3bb5e066f..0dc102a0c4 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -9,6 +9,7 @@ import { DatasourcePlus, DatasourceFeature, ConnectionInfo, + SourceName, } from "@budibase/types" import { getSqlQuery, @@ -21,7 +22,7 @@ import dayjs from "dayjs" import { NUMBER_REGEX } from "../utilities" import Sql from "./base/sql" import { MySQLColumn } from "./base/types" - +import { getReadableErrorMessage } from "./base/errorMapping" import mysql from "mysql2/promise" interface MySQLConfig extends mysql.ConnectionOptions { @@ -174,7 +175,12 @@ class MySQLIntegration extends Sql implements DatasourcePlus { ) response.connected = result?.checkRes == 2 } catch (e: any) { - response.error = e.message as string + let readableMessage = getReadableErrorMessage(SourceName.MYSQL, e.errno) + if (readableMessage) { + response.error = readableMessage + } else { + response.error = e.message as string + } } return response } @@ -213,6 +219,13 @@ class MySQLIntegration extends Sql implements DatasourcePlus { // Node MySQL is callback based, so we must wrap our call in a promise const response = await this.client!.query(query.sql, bindings) return response[0] + } catch (err: any) { + let readableMessage = getReadableErrorMessage(SourceName.MYSQL, err.errno) + if (readableMessage) { + throw new Error(readableMessage) + } else { + throw new Error(err.message as string) + } } finally { if (opts?.connect && this.client) { await this.disconnect() diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index b1f20f97ec..e45eaa7b63 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -8,6 +8,7 @@ import { DatasourcePlus, DatasourceFeature, ConnectionInfo, + SourceName, } from "@budibase/types" import { getSqlQuery, @@ -21,6 +22,7 @@ import { PostgresColumn } from "./base/types" import { escapeDangerousCharacters } from "../utilities" import { Client, ClientConfig, types } from "pg" +import { getReadableErrorMessage } from "./base/errorMapping" // Return "date" and "timestamp" types as plain strings. // This lets us reference the original stored timezone. @@ -182,6 +184,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus { await this.openConnection() response.connected = true } catch (e: any) { + console.log(e) response.error = e.message as string } finally { await this.closeConnection() @@ -240,10 +243,17 @@ class PostgresIntegration extends Sql implements DatasourcePlus { } try { return await client.query(query.sql, query.bindings || []) - } catch (err) { + } catch (err: any) { await this.closeConnection() - // @ts-ignore - throw new Error(err) + let readableMessage = getReadableErrorMessage( + SourceName.POSTGRES, + err.errno + ) + if (readableMessage) { + throw new Error(readableMessage) + } else { + throw new Error(err.message as string) + } } finally { if (close) { await this.closeConnection() From cf0300973a352c4402cad18614bc1a57e76fb467 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 27 Jun 2023 15:28:10 +0100 Subject: [PATCH 2/7] add error mapping system --- .../src/integrations/base/errorMapping.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 packages/server/src/integrations/base/errorMapping.ts diff --git a/packages/server/src/integrations/base/errorMapping.ts b/packages/server/src/integrations/base/errorMapping.ts new file mode 100644 index 0000000000..80af9d587c --- /dev/null +++ b/packages/server/src/integrations/base/errorMapping.ts @@ -0,0 +1,27 @@ +import { SourceName } from "@budibase/types" + +const mysqlErrorMessages: Record = { + 1045: "Access denied for the specified user. User does not have the necessary privileges or the provided credentials are incorrect. Please verify the credentials, and ensure that the user has appropriate permissions.", + 1049: "The specified database does not exist. Please verify that the database name is correct.", +} + +const postgresErrorMessages: Record = { + 28: "Connection timed out. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", + 3: "Connection timed out. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", + 4: "Connection refused. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", + 1017: "Access denied for the specified user. User does not have the necessary privileges or the provided credentials are incorrect. Please verify the credentials, and ensure that the user has appropriate permissions.", + 1049: "The specified database does not exist. Please verify that the database name is correct.", +} + +const sqlServerErrorMessages: Record = {} + +export const getReadableErrorMessage = (type: string, errno: number) => { + switch (type) { + case SourceName.MYSQL: + return mysqlErrorMessages[errno] + case SourceName.POSTGRES: + return postgresErrorMessages[errno] + case SourceName.SQL_SERVER: + return sqlServerErrorMessages[errno] + } +} From c35e403c5e113085796392c73c8a98e2d40f7228 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 28 Jun 2023 09:11:50 +0100 Subject: [PATCH 3/7] fix error not showing as new row has no focusedCellID --- .../frontend-core/src/components/grid/stores/rows.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/stores/rows.js b/packages/frontend-core/src/components/grid/stores/rows.js index 198c05025c..d83f3bf367 100644 --- a/packages/frontend-core/src/components/grid/stores/rows.js +++ b/packages/frontend-core/src/components/grid/stores/rows.js @@ -206,7 +206,14 @@ export const deriveStores = context => { focusedCellId.set(`${rowId}-${keys[0]}`) } else { // Some other error - just update the current cell - validation.actions.setError(get(focusedCellId), error?.message || "Error") + if (get(focusedCellId)) { + validation.actions.setError( + get(focusedCellId), + error?.message || "Error" + ) + } else { + notifications.error(error?.message || "Error") + } } } From fed6a83bcacef678b90fa84048559e7a21434158 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 28 Jun 2023 09:18:41 +0100 Subject: [PATCH 4/7] remove incorrect psql codes --- packages/server/src/integrations/base/errorMapping.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/server/src/integrations/base/errorMapping.ts b/packages/server/src/integrations/base/errorMapping.ts index 80af9d587c..38e9ee3c39 100644 --- a/packages/server/src/integrations/base/errorMapping.ts +++ b/packages/server/src/integrations/base/errorMapping.ts @@ -5,13 +5,7 @@ const mysqlErrorMessages: Record = { 1049: "The specified database does not exist. Please verify that the database name is correct.", } -const postgresErrorMessages: Record = { - 28: "Connection timed out. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", - 3: "Connection timed out. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", - 4: "Connection refused. Please verify that the database host and port are correct, and that the database is accepting TCP/IP connections.", - 1017: "Access denied for the specified user. User does not have the necessary privileges or the provided credentials are incorrect. Please verify the credentials, and ensure that the user has appropriate permissions.", - 1049: "The specified database does not exist. Please verify that the database name is correct.", -} +const postgresErrorMessages: Record = {} const sqlServerErrorMessages: Record = {} From 87768fd5774954309aff9a5cd31aa729870b6eec Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 28 Jun 2023 09:28:40 +0100 Subject: [PATCH 5/7] update error messages: --- .../server/src/integrations/base/errorMapping.ts | 15 +++++++++++++-- .../server/src/integrations/microsoftSqlServer.ts | 2 +- packages/server/src/integrations/postgres.ts | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/server/src/integrations/base/errorMapping.ts b/packages/server/src/integrations/base/errorMapping.ts index 38e9ee3c39..592d368cc0 100644 --- a/packages/server/src/integrations/base/errorMapping.ts +++ b/packages/server/src/integrations/base/errorMapping.ts @@ -5,9 +5,20 @@ const mysqlErrorMessages: Record = { 1049: "The specified database does not exist. Please verify that the database name is correct.", } -const postgresErrorMessages: Record = {} +const postgresErrorMessages: Record = { + "23505": "Duplicate key value violates unique constraint.", + "23502": "Null value not allowed for a column.", + "23503": "Foreign key violation.", + "23514": "Check constraint violation.", + "42703": "Undefined column.", + "42P01": "Undefined table.", +} -const sqlServerErrorMessages: Record = {} +const sqlServerErrorMessages: Record = { + 547: "The INSERT statement conflicted with the FOREIGN KEY constraint.", + 2601: "Cannot insert duplicate key row in object.", + 515: "Cannot insert the value NULL into column.", +} export const getReadableErrorMessage = (type: string, errno: number) => { switch (type) { diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index ee3cbc9970..99c1454965 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -182,7 +182,7 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { } catch (err: any) { let readableMessage = getReadableErrorMessage( SourceName.SQL_SERVER, - err.errno + err.number ) if (readableMessage) { throw new Error(readableMessage) diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index e45eaa7b63..ae82ec9c9b 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -247,7 +247,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus { await this.closeConnection() let readableMessage = getReadableErrorMessage( SourceName.POSTGRES, - err.errno + err.code ) if (readableMessage) { throw new Error(readableMessage) From c8ef273f6960ddb99812fbd6d6bef3cafaf7a6aa Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Wed, 28 Jun 2023 11:11:01 +0100 Subject: [PATCH 6/7] removing fix as a more elegant fix introduced in #11049 --- .../frontend-core/src/components/grid/stores/rows.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/rows.js b/packages/frontend-core/src/components/grid/stores/rows.js index d83f3bf367..198c05025c 100644 --- a/packages/frontend-core/src/components/grid/stores/rows.js +++ b/packages/frontend-core/src/components/grid/stores/rows.js @@ -206,14 +206,7 @@ export const deriveStores = context => { focusedCellId.set(`${rowId}-${keys[0]}`) } else { // Some other error - just update the current cell - if (get(focusedCellId)) { - validation.actions.setError( - get(focusedCellId), - error?.message || "Error" - ) - } else { - notifications.error(error?.message || "Error") - } + validation.actions.setError(get(focusedCellId), error?.message || "Error") } } From 592a35d0c38f65a27a0849972e0f876e90c33d2d Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 28 Jun 2023 17:37:40 +0100 Subject: [PATCH 7/7] Updating pro,. --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index f4b8449aac..544c7e067d 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit f4b8449aac9bd265214396afbdce7ff984a2ae34 +Subproject commit 544c7e067de69832469cde673e59501480d6d98a