All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ldbc.connector.exception.SQLException.scala Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2023-2024 by Takahiko Tominaga
 * This software is licensed under the MIT License (MIT).
 * For more information see LICENSE or https://opensource.org/licenses/MIT
 */

package ldbc.connector.exception

import scala.collection.immutable.SortedMap

import cats.syntax.all.*

import org.typelevel.otel4s.Attribute

import ldbc.connector.data.Parameter
import ldbc.connector.util.Pretty

/**
 * 

An exception that provides information on a database access * error or other errors. * *

Each SQLException provides several kinds of information: *

    *
  • a string describing the error. This is used as the Java Exception * message, available via the method getMessage. *
  • a "SQLstate" string, which follows either the XOPEN SQLstate conventions * or the SQL:2003 conventions. * The values of the SQLState string are described in the appropriate spec. * The DatabaseMetaData method getSQLStateType * can be used to discover whether the driver returns the XOPEN type or * the SQL:2003 type. *
  • an integer error code that is specific to each vendor. Normally this will * be the actual error code returned by the underlying database. *
  • a chain to a next Exception. This can be used to provide additional * error information. *
  • the causal relationship, if any for this SQLException. *
*/ class SQLException( message: String, sqlState: Option[String] = None, vendorCode: Option[Int] = None, sql: Option[String] = None, detail: Option[String] = None, hint: Option[String] = None, params: SortedMap[Int, Parameter] = SortedMap.empty ) extends Exception: /** * Summarize error information into attributes. */ def fields: List[Attribute[?]] = val builder = List.newBuilder[Attribute[?]] builder += Attribute("error.message", message) sqlState.foreach(a => builder += Attribute("error.sqlstate", a)) vendorCode.foreach(a => builder += Attribute("error.vendorCode", a.toLong)) sql.foreach(a => builder += Attribute("error.sql", a)) detail.foreach(a => builder += Attribute("error.detail", a)) hint.foreach(a => builder += Attribute("error.hint", a)) params.foreach { case (i, p) => builder += Attribute(s"error.parameter.$i.type", p.columnDataType.name) builder += Attribute(s"error.parameter.$i.value", p.toString) } builder.result() protected def width = 80 // wrap here def labeled(label: String, s: String): String = if s.isEmpty then "" else "\n|" + label + Console.CYAN + Pretty.wrap( width - label.length, s, s"${ Console.RESET }\n${ Console.CYAN }" + label.map(_ => ' ') ) + Console.RESET protected def title: String = s"MySQL ERROR${ vendorCode.fold("")(code => s" code $code") }${ sqlState.fold("")(state => s" ($state)") }" protected def header: String = s"""| |$title |${ labeled(" Problem: ", message) }${ labeled(" Detail: ", detail.orEmpty) }${ labeled( " Hint: ", hint.orEmpty ) } | |""".stripMargin protected def statement: String = sql.foldMap { sql => s"""|The statement under consideration is | | ${ Console.GREEN }$sql${ Console.RESET } | |""".stripMargin } protected def args: String = def formatValue(s: String) = s"${ Console.GREEN }$s${ Console.RESET }" if params.isEmpty then "" else s"""|and the arguments were | | ${ params .map { case (i, p) => f"$$$i ${ p.columnDataType.name }%-10s ${ formatValue(p.toString) }" } .mkString("\n| ") } | |""".stripMargin protected def sections: List[String] = List(header, statement, args) final override def getMessage: String = sections.combineAll.linesIterator .map("🔥 " + _) .mkString("\n", "\n", s"\n\n${ getClass.getName }: $message")




© 2015 - 2024 Weber Informatics LLC | Privacy Policy