Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions packages/client-common/src/error/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const errorRe =
/(Code|Error): (?<code>\d+).*Exception: (?<message>.+)\((?<type>(?=.+[A-Z]{3})[A-Z0-9_]+?)\)/s

interface ParsedClickHouseError {
message: string
code: string
type?: string
}

/** An error that is thrown by the ClickHouse server. */
export class ClickHouseError extends Error {
readonly code: string
readonly type: string | undefined
constructor({ message, code, type }: ParsedClickHouseError) {
super(message)
this.code = code
this.type = type

// Set the prototype explicitly, see:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(this, ClickHouseError.prototype)
}
}

export function parseError(input: string | Error): ClickHouseError | Error {
const inputIsError = input instanceof Error
const message = inputIsError ? input.message : input
const match = message.match(errorRe)
const groups = match?.groups as ParsedClickHouseError | undefined
if (groups) {
return new ClickHouseError(groups)
} else {
return inputIsError ? input : new Error(input)
}
}

export function getCurrentStackTrace(): string {
const originalStackTraceLimit = Error.stackTraceLimit
Error.stackTraceLimit = 100
const stack = new Error().stack
Error.stackTraceLimit = originalStackTraceLimit

if (!stack) return ''

let foundNewLines = 0
let idx = 0

// Skip the first three lines of the stack trace, containing useless information
// - Text `Error`
// - Info about this function call
// - Info about the originator of this function call, e.g., `request`
while (foundNewLines < 3) {
idx = stack.indexOf('\n', idx + 1)
if (idx === -1) {
return ''
} else {
foundNewLines++
}
}

return stack.substring(idx + 1)
}

export function addStackTrace<E extends Error>(err: E, stackTrace: string): E {
if (err.stack) {
const firstNewlineIndex = err.stack.indexOf('\n')
const firstLine = err.stack.substring(0, firstNewlineIndex)
const errStack = err.stack.substring(firstNewlineIndex + 1)
err.stack = `${firstLine}\n${stackTrace}\n${errStack}`
}
return err
}
2 changes: 1 addition & 1 deletion packages/client-common/src/error/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './parse_error'
export * from './error'
34 changes: 0 additions & 34 deletions packages/client-common/src/error/parse_error.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/client-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export type {
} from './parse'
export { SimpleColumnTypes, parseColumnType } from './parse'

/** For implementations usage only - should not be re-exported */
/** For implementation usage only - should not be re-exported */
export {
formatQuerySettings,
formatQueryParams,
Expand Down Expand Up @@ -112,7 +112,7 @@ export {
isJWTAuth,
} from './utils'
export { LogWriter, DefaultLogger, type LogWriterParams } from './logger'
export { parseError } from './error'
export { parseError, getCurrentStackTrace, addStackTrace } from './error'
export type {
CompressionSettings,
Connection,
Expand Down
Loading