mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-10 06:07:16 +01:00
Some sub-systems like btcwallet will return an error from the database, but they won't properly wrap it. As a result, we were unable to actually catch the serialization errors in the first place. To work around this, we'll now attempt to parse the error string directly.
54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
//go:build kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64))
|
|
|
|
package sqlbase
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"modernc.org/sqlite"
|
|
sqlite3 "modernc.org/sqlite/lib"
|
|
)
|
|
|
|
// parseSqliteError attempts to parse a sqlite error as a database agnostic
|
|
// SQL error.
|
|
func parseSqliteError(err error) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
// If the error isn't wrapped properly, the errors.As call with fail,
|
|
// so we'll also try to check the expected error message directly.
|
|
// This is taken from:
|
|
// https://gitlab.com/cznic/sqlite/-/blob/v1.25.0/sqlite.go#L75.
|
|
const sqliteErrMsg = "SQLITE_BUSY"
|
|
if strings.Contains(err.Error(), sqliteErrMsg) {
|
|
return &ErrSerializationError{
|
|
DBError: err,
|
|
}
|
|
}
|
|
|
|
var sqliteErr *sqlite.Error
|
|
if !errors.As(err, &sqliteErr) {
|
|
return nil
|
|
}
|
|
|
|
switch sqliteErr.Code() {
|
|
// Handle unique constraint violation error.
|
|
case sqlite3.SQLITE_CONSTRAINT_UNIQUE:
|
|
return &ErrSQLUniqueConstraintViolation{
|
|
DBError: sqliteErr,
|
|
}
|
|
|
|
// Database is currently busy, so we'll need to try again.
|
|
case sqlite3.SQLITE_BUSY:
|
|
return &ErrSerializationError{
|
|
DBError: sqliteErr,
|
|
}
|
|
|
|
default:
|
|
return fmt.Errorf("unknown sqlite error: %w", sqliteErr)
|
|
}
|
|
}
|