Merge pull request #11047 from Budibase/feat/surface-sql-errors
Surface SQL errors
This commit is contained in:
commit
64c6333f9b
|
@ -0,0 +1,32 @@
|
|||
import { SourceName } from "@budibase/types"
|
||||
|
||||
const mysqlErrorMessages: Record<number, string> = {
|
||||
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<string, string> = {
|
||||
"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<number, string> = {
|
||||
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) {
|
||||
case SourceName.MYSQL:
|
||||
return mysqlErrorMessages[errno]
|
||||
case SourceName.POSTGRES:
|
||||
return postgresErrorMessages[errno]
|
||||
case SourceName.SQL_SERVER:
|
||||
return sqlServerErrorMessages[errno]
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
import sqlServer from "mssql"
|
||||
const DEFAULT_SCHEMA = "dbo"
|
||||
|
||||
|
@ -252,9 +254,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.number
|
||||
)
|
||||
if (readableMessage) {
|
||||
throw new Error(readableMessage)
|
||||
} else {
|
||||
throw new Error(err.message as string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -175,7 +176,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
|
||||
}
|
||||
|
@ -214,6 +220,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()
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
DatasourcePlus,
|
||||
DatasourceFeature,
|
||||
ConnectionInfo,
|
||||
SourceName,
|
||||
} from "@budibase/types"
|
||||
import {
|
||||
getSqlQuery,
|
||||
|
@ -22,6 +23,7 @@ import { PostgresColumn } from "./base/types"
|
|||
import { escapeDangerousCharacters } from "../utilities"
|
||||
|
||||
import { Client, ClientConfig, types } from "pg"
|
||||
import { getReadableErrorMessage } from "./base/errorMapping"
|
||||
import { exec } from "child_process"
|
||||
import { storeTempFile } from "../utilities/fileSystem"
|
||||
|
||||
|
@ -187,6 +189,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()
|
||||
|
@ -245,10 +248,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.code
|
||||
)
|
||||
if (readableMessage) {
|
||||
throw new Error(readableMessage)
|
||||
} else {
|
||||
throw new Error(err.message as string)
|
||||
}
|
||||
} finally {
|
||||
if (close) {
|
||||
await this.closeConnection()
|
||||
|
|
Loading…
Reference in New Issue