[KYUUBI #670] KyuubiSQLException support sqlState and errorCode
<!-- Thanks for sending a pull request! Here are some tips for you: 1. If this is your first time, please read our contributor guidelines: https://kyuubi.readthedocs.io/en/latest/community/contributions.html 2. If the PR is related to an issue in https://github.com/NetEase/kyuubi/issues, add '[KYUUBI #XXXX]' in your PR title, e.g., '[KYUUBI #XXXX] Your PR title ...'. 3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][KYUUBI #XXXX] Your PR title ...'. --> ### _Why are the changes needed?_ <!-- Please clarify why the changes are needed. For instance, 1. If you add a feature, you can talk about the use case of it. 2. If you fix a bug, you can clarify why it is a bug. --> #670 ### _How was this patch tested?_ - [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible - [ ] Add screenshots for manual tests if appropriate - [x] [Run test](https://kyuubi.readthedocs.io/en/latest/tools/testing.html#running-tests) locally before make a pull request Closes #674 from pan3793/sql-error-code. Closes #670 08c95915 [Cheng Pan] address comments e0808bc5 [Cheng Pan] address comments e14e884b [Cheng Pan] KyuubiSQLException support sqlState and errorCode Authored-by: Cheng Pan <379377944@qq.com> Signed-off-by: ulysses-you <ulyssesyou18@gmail.com>
This commit is contained in:
parent
b9079b698d
commit
43d60bd1b1
@ -26,7 +26,20 @@ import scala.collection.JavaConverters._
|
||||
|
||||
import org.apache.hive.service.rpc.thrift.{TStatus, TStatusCode}
|
||||
|
||||
class KyuubiSQLException(msg: String, cause: Throwable) extends SQLException(msg, cause) {
|
||||
/**
|
||||
* @param reason a description of the exception
|
||||
* @param sqlState an XOPEN or SQL:2003 code identifying the exception
|
||||
* @param vendorCode a database vendor-specific exception code
|
||||
* @param cause the underlying reason for this [[SQLException]]
|
||||
* (which is saved for later retrieval by the `getCause()` method);
|
||||
* may be null indicating the cause is non-existent or unknown.
|
||||
*/
|
||||
class KyuubiSQLException(reason: String, sqlState: String, vendorCode: Int, cause: Throwable)
|
||||
extends SQLException(reason, sqlState, vendorCode, cause) {
|
||||
|
||||
// for reflection
|
||||
def this(msg: String, cause: Throwable) = this(msg, null, 0, cause)
|
||||
|
||||
/**
|
||||
* Converts current object to a [[TStatus]] object
|
||||
*
|
||||
@ -47,22 +60,24 @@ object KyuubiSQLException {
|
||||
private final val HEAD_MARK: String = "*"
|
||||
private final val SEPARATOR: Char = ':'
|
||||
|
||||
def apply(msg: String, throwable: Throwable): KyuubiSQLException = {
|
||||
new KyuubiSQLException(msg, findCause(throwable))
|
||||
def apply(
|
||||
msg: String,
|
||||
cause: Throwable = null,
|
||||
sqlState: String = null,
|
||||
vendorCode: Int = 0): KyuubiSQLException = {
|
||||
new KyuubiSQLException(msg, sqlState, vendorCode, findCause(cause))
|
||||
}
|
||||
def apply(cause: Throwable): KyuubiSQLException = {
|
||||
val theCause = findCause(cause)
|
||||
new KyuubiSQLException(theCause.getMessage, theCause)
|
||||
apply(theCause.getMessage, theCause)
|
||||
}
|
||||
|
||||
def apply(msg: String): KyuubiSQLException = new KyuubiSQLException(msg, null)
|
||||
|
||||
def apply(tStatus: TStatus): KyuubiSQLException = {
|
||||
val msg = tStatus.getErrorMessage
|
||||
val cause = toCause(tStatus.getInfoMessages.asScala)
|
||||
cause match {
|
||||
case k: KyuubiSQLException if k.getMessage == msg => k
|
||||
case _ => apply(msg, cause)
|
||||
case _ => apply(msg, cause, tStatus.getSqlState, tStatus.getErrorCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +119,7 @@ class OperationLog(path: Path) extends Logging {
|
||||
case e: IOException =>
|
||||
val absPath = path.toAbsolutePath
|
||||
val opHandle = absPath.getFileName
|
||||
throw new KyuubiSQLException(s"Operation[$opHandle] log file $absPath is not found", e)
|
||||
throw KyuubiSQLException(s"Operation[$opHandle] log file $absPath is not found", e)
|
||||
}
|
||||
val tColumn = TColumn.stringVal(new TStringColumn(logs, ByteBuffer.allocate(0)))
|
||||
val tRow = new TRowSet(0, new java.util.ArrayList[TRow](logs.size()))
|
||||
|
||||
@ -117,7 +117,7 @@ object KyuubiAuthenticationFactory {
|
||||
}
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
throw new KyuubiSQLException(
|
||||
throw KyuubiSQLException(
|
||||
"Failed to validate proxy privilege of " + realUser + " for " + proxyUser, e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ class KyuubiSQLExceptionSuite extends KyuubiFunSuite {
|
||||
|
||||
val e0 = new KyuubiException(msg0)
|
||||
val e1 = new KyuubiException(msg1, e0)
|
||||
val e2 = new KyuubiSQLException(msg2, e1)
|
||||
val e2 = KyuubiSQLException(msg2, e1)
|
||||
assert(e2.toTStatus === KyuubiSQLException.toTStatus(e2))
|
||||
|
||||
val e3 = KyuubiSQLException(e2.toTStatus)
|
||||
@ -51,6 +51,13 @@ class KyuubiSQLExceptionSuite extends KyuubiFunSuite {
|
||||
val e5 = KyuubiSQLException(e0)
|
||||
assert(e5.getMessage === msg0)
|
||||
assert(e5.getCause === e0)
|
||||
|
||||
val ts1 = KyuubiSQLException(msg2, e0, "01001", 1).toTStatus
|
||||
assert(ts1.getStatusCode === TStatusCode.ERROR_STATUS)
|
||||
assert(ts1.getSqlState === "01001")
|
||||
assert(ts1.getErrorCode === 1)
|
||||
assert(ts1.getErrorMessage === msg2)
|
||||
assert(ts1.getInfoMessages.get(0).startsWith("*"))
|
||||
}
|
||||
|
||||
test("find the root cause") {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user