Exception Handling with Kotlin Exposed - 如何捕获违反唯一约束的异常?
Exception Handling with Kotlin Exposed - How to catch unique constraint violation exception?
我在 table 的列中添加了唯一约束。当约束被违反时,它会抛出一个我无法捕获并传达给用户的异常。
Exposed: Transaction attempt #0 failed: java.sql.BatchUpdateException: Batch entry 0 INSERT INTO templates (created_at, is_deleted, name, sections) VALUES ('2018-10-03 16:31:25.732+05:30', 'FALSE', 'Template1', '[{"title":"Introduction"}]')
RETURNING * was aborted: ERROR: duplicate key value violates unique constraint "templates_name_key"
Detail: Key (name)=(Template1) already exists. Call getNextException to see other errors in the batch.. Statement(s): INSERT INTO templates (created_at, is_deleted, name, sections) VALUES (?, ?, ?, ?)
! org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "templates_name_key"
! Detail: Key (name)=(Template1) already exists.
- 如何使用用户可读消息捕获此类 SQL 异常?
- 是否有捕获这些异常的最佳实践?
- 我们应该在交易内部还是外部捕获它们?有这样的必要吗?
下面是我试过的片段。
return try {
val template: TemplateSerializer = transaction {
val newTemplate = Template.insert(request)
TemplateSerializer.serialize(newTemplate)
}
Response.status(201).entity(template).build()
} catch (e: Exception) {
if(e is SQLIntegrityConstraintViolationException) {
resourceLogger.error("SQL constraint violated")
} else if(e is BatchUpdateException) {
resourceLogger.error("SQL constraint violated")
} else
resourceLogger.error(e.message)
Response.status(422).entity(mapOf("error" to true, "message" to "Insertion failed")).build()
}
根本没有打印消息SQL constraint violated
。也尝试过使用不同的 Exception 类 进行多次捕获。没有任何效果。
发送此类一般性错误消息无济于事。
Exposed throws ExposedSQLException
是 SQLException
的子类型,可以通过 causeByQueries()
函数访问最新执行的查询(可能导致原始异常)。原始异常可通过 cause
属性.
访问
return try {
val template: TemplateSerializer = transaction {
val newTemplate = Template.insert(request)
TemplateSerializer.serialize(newTemplate)
}
Response.status(201).entity(template).build()
} catch (e: Exception) {
val original = (e as? ExposedSQLException)?.cause
when (original) {
is SQLIntegrityConstraintViolationException ->
resourceLogger.error("SQL constraint violated")
is BatchUpdateException ->
resourceLogger.error("SQL constraint violated")
else ->
resourceLogger.error(e.message)
}
Response.status(422).entity(mapOf("error" to true, "message" to "Insertion failed")).build()
您可以检查 sqlState
。
看起来像:
try {
userService.insertUser(user)
} catch (e: ExposedSQLException) {
val isUniqueConstraintError = e.sqlState == "23505"
}
您可以从那里获取正确的错误代码:
我在 table 的列中添加了唯一约束。当约束被违反时,它会抛出一个我无法捕获并传达给用户的异常。
Exposed: Transaction attempt #0 failed: java.sql.BatchUpdateException: Batch entry 0 INSERT INTO templates (created_at, is_deleted, name, sections) VALUES ('2018-10-03 16:31:25.732+05:30', 'FALSE', 'Template1', '[{"title":"Introduction"}]')
RETURNING * was aborted: ERROR: duplicate key value violates unique constraint "templates_name_key"
Detail: Key (name)=(Template1) already exists. Call getNextException to see other errors in the batch.. Statement(s): INSERT INTO templates (created_at, is_deleted, name, sections) VALUES (?, ?, ?, ?)
! org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "templates_name_key"
! Detail: Key (name)=(Template1) already exists.
- 如何使用用户可读消息捕获此类 SQL 异常?
- 是否有捕获这些异常的最佳实践?
- 我们应该在交易内部还是外部捕获它们?有这样的必要吗?
下面是我试过的片段。
return try {
val template: TemplateSerializer = transaction {
val newTemplate = Template.insert(request)
TemplateSerializer.serialize(newTemplate)
}
Response.status(201).entity(template).build()
} catch (e: Exception) {
if(e is SQLIntegrityConstraintViolationException) {
resourceLogger.error("SQL constraint violated")
} else if(e is BatchUpdateException) {
resourceLogger.error("SQL constraint violated")
} else
resourceLogger.error(e.message)
Response.status(422).entity(mapOf("error" to true, "message" to "Insertion failed")).build()
}
根本没有打印消息SQL constraint violated
。也尝试过使用不同的 Exception 类 进行多次捕获。没有任何效果。
发送此类一般性错误消息无济于事。
Exposed throws ExposedSQLException
是 SQLException
的子类型,可以通过 causeByQueries()
函数访问最新执行的查询(可能导致原始异常)。原始异常可通过 cause
属性.
return try {
val template: TemplateSerializer = transaction {
val newTemplate = Template.insert(request)
TemplateSerializer.serialize(newTemplate)
}
Response.status(201).entity(template).build()
} catch (e: Exception) {
val original = (e as? ExposedSQLException)?.cause
when (original) {
is SQLIntegrityConstraintViolationException ->
resourceLogger.error("SQL constraint violated")
is BatchUpdateException ->
resourceLogger.error("SQL constraint violated")
else ->
resourceLogger.error(e.message)
}
Response.status(422).entity(mapOf("error" to true, "message" to "Insertion failed")).build()
您可以检查 sqlState
。
看起来像:
try {
userService.insertUser(user)
} catch (e: ExposedSQLException) {
val isUniqueConstraintError = e.sqlState == "23505"
}
您可以从那里获取正确的错误代码: