aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-12-17 14:50:43 +0100
committerRobert Hensing <robert@roberthensing.nl>2022-12-17 14:51:37 +0100
commitc965f35de71cc9d88f912f6b90fd7213601e6eb8 (patch)
tree78a578dcdbcf4dbc1790a80fcd5a76f7f44ab455
parent26c7602c390f8c511f326785b570918b2f468892 (diff)
Improve sqlite error messages
They did not include the detailed error message, losing essential information for troubleshooting. Example message: warning: creating statement 'insert or rplace into NARs(cache, hashPart, namePart, url, compression, fileHash, fileSize, narHash, narSize, refs, deriver, sigs, ca, timestamp, present) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)': at offset 10: SQL logic error, near "rplace": syntax error (in '/tmp/nix-shell.grQ6f7/nix-test/tests/binary-cache/test-home/.cache/nix/binary-cache-v6.sqlite') It's not the best example; more important information will be in the message for e.g. a constraint violation. I don't see why this specific error is printed as a warning, but that's for another commit.
-rw-r--r--src/libstore/sqlite.cc15
-rw-r--r--src/libstore/sqlite.hh11
2 files changed, 16 insertions, 10 deletions
diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc
index 2090beabd..6c350888f 100644
--- a/src/libstore/sqlite.cc
+++ b/src/libstore/sqlite.cc
@@ -8,12 +8,15 @@
namespace nix {
-SQLiteError::SQLiteError(const char *path, int errNo, int extendedErrNo, hintformat && hf)
- : Error(""), path(path), errNo(errNo), extendedErrNo(extendedErrNo)
+SQLiteError::SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, hintformat && hf)
+ : Error(""), path(path), errMsg(errMsg), errNo(errNo), extendedErrNo(extendedErrNo), offset(offset)
{
- err.msg = hintfmt("%s: %s (in '%s')",
+ auto offsetStr = (offset == -1) ? "" : "at offset " + std::to_string(offset) + ": ";
+ err.msg = hintfmt("%s: %s%s, %s (in '%s')",
normaltxt(hf.str()),
+ offsetStr,
sqlite3_errstr(extendedErrNo),
+ errMsg,
path ? path : "(in-memory)");
}
@@ -21,11 +24,13 @@ SQLiteError::SQLiteError(const char *path, int errNo, int extendedErrNo, hintfor
{
int err = sqlite3_errcode(db);
int exterr = sqlite3_extended_errcode(db);
+ int offset = sqlite3_error_offset(db);
auto path = sqlite3_db_filename(db, nullptr);
+ auto errMsg = sqlite3_errmsg(db);
if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
- auto exp = SQLiteBusy(path, err, exterr, std::move(hf));
+ auto exp = SQLiteBusy(path, errMsg, err, exterr, offset, std::move(hf));
exp.err.msg = hintfmt(
err == SQLITE_PROTOCOL
? "SQLite database '%s' is busy (SQLITE_PROTOCOL)"
@@ -33,7 +38,7 @@ SQLiteError::SQLiteError(const char *path, int errNo, int extendedErrNo, hintfor
path ? path : "(in-memory)");
throw exp;
} else
- throw SQLiteError(path, err, exterr, std::move(hf));
+ throw SQLiteError(path, errMsg, err, exterr, offset, std::move(hf));
}
SQLite::SQLite(const Path & path, bool create)
diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh
index 1d1c553ea..1853731a2 100644
--- a/src/libstore/sqlite.hh
+++ b/src/libstore/sqlite.hh
@@ -98,21 +98,22 @@ struct SQLiteTxn
struct SQLiteError : Error
{
- const char *path;
- int errNo, extendedErrNo;
+ std::string path;
+ std::string errMsg;
+ int errNo, extendedErrNo, offset;
template<typename... Args>
[[noreturn]] static void throw_(sqlite3 * db, const std::string & fs, const Args & ... args) {
throw_(db, hintfmt(fs, args...));
}
- SQLiteError(const char *path, int errNo, int extendedErrNo, hintformat && hf);
+ SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, hintformat && hf);
protected:
template<typename... Args>
- SQLiteError(const char *path, int errNo, int extendedErrNo, const std::string & fs, const Args & ... args)
- : SQLiteError(path, errNo, extendedErrNo, hintfmt(fs, args...))
+ SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, const std::string & fs, const Args & ... args)
+ : SQLiteError(path, errNo, extendedErrNo, offset, hintfmt(fs, args...))
{ }
[[noreturn]] static void throw_(sqlite3 * db, hintformat && hf);