@@ -73,6 +73,27 @@ static Napi::Value SignalTokenize(const Napi::CallbackInfo& info) {
7373 return result;
7474}
7575
76+ // Utils
77+
78+ Napi::Error FormatError (Napi::Env env, const char * format, ...) {
79+ va_list args;
80+
81+ va_start (args, format);
82+
83+ // Get buffer size
84+ auto size = vsnprintf (nullptr , 0 , format, args);
85+
86+ // Allocate and fill the string
87+ auto buf = new char [size + 1 ];
88+ vsnprintf (buf, size + 1 , format, args);
89+
90+ va_end (args);
91+
92+ auto err = Napi::Error::New (env, buf);
93+ delete[] buf;
94+ return err;
95+ }
96+
7697// Database
7798
7899Napi::Object Database::Init (Napi::Env env, Napi::Object exports) {
@@ -127,10 +148,8 @@ Napi::Value Database::Open(const Napi::CallbackInfo& info) {
127148 sqlite3* handle = nullptr ;
128149 int r = sqlite3_open_v2 (path_utf8.c_str (), &handle, flags, nullptr );
129150 if (r != SQLITE_OK) {
130- char buf[1024 ];
131-
132- snprintf (buf, sizeof (buf), " sqlite open error: %s" , sqlite3_errstr (r));
133- NAPI_THROW (Napi::Error::New (env, buf), Napi::Value ());
151+ NAPI_THROW (FormatError (env, " sqlite open error: %s" , sqlite3_errstr (r)),
152+ Napi::Value ());
134153 }
135154
136155 auto db = new Database (env, handle);
@@ -209,20 +228,18 @@ Napi::Value Database::Exec(const Napi::CallbackInfo& info) {
209228}
210229
211230Napi::Value Database::ThrowSqliteError (Napi::Env env, int error) {
212- char buf[1024 ];
213-
214231 assert (handle_ != nullptr );
215232 const char * msg = sqlite3_errmsg (handle_);
216233 int offset = sqlite3_error_offset (handle_);
217234 int extended = sqlite3_extended_errcode (handle_);
218235 if (offset == -1 ) {
219- snprintf (buf, sizeof (buf), " sqlite error(%d): %s" , extended, msg);
236+ NAPI_THROW (FormatError (env, " sqlite error(%d): %s" , extended, msg),
237+ Napi::Value ());
220238 } else {
221- snprintf (buf, sizeof (buf), " sqlite error(%d): %s, offset: %d" , extended,
222- msg, offset);
239+ NAPI_THROW (FormatError (env, " sqlite error(%d): %s, offset: %d" , extended,
240+ msg, offset),
241+ Napi::Value ());
223242 }
224-
225- NAPI_THROW (Napi::Error::New (env, buf), Napi::Value ());
226243}
227244
228245fts5_api* Database::GetFTS5API (Napi::Env env) {
@@ -499,8 +516,6 @@ Napi::Value Statement::Step(const Napi::CallbackInfo& info) {
499516}
500517
501518bool Statement::BindParams (Napi::Env env, Napi::Value params) {
502- char buf[1024 ];
503-
504519 int key_count = sqlite3_bind_parameter_count (handle_);
505520
506521 if (params.IsNull ()) {
@@ -512,29 +527,29 @@ bool Statement::BindParams(Napi::Env env, Napi::Value params) {
512527 return true ;
513528 }
514529
515- snprintf (buf, sizeof (buf) , " Expected %d parameters, got 0" , key_count);
516- NAPI_THROW ( Napi::Error::New (env, buf), false );
530+ NAPI_THROW ( FormatError (env , " Expected %d parameters, got 0" , key_count),
531+ false );
517532 } else if (params.IsArray ()) {
518533 auto list = params.As <Napi::Array>();
519534 auto list_len = static_cast <int >(list.Length ());
520535 if (list_len != key_count) {
521- snprintf (buf, sizeof (buf) , " Expected %d parameters, got %d" , key_count,
522- list_len);
523- NAPI_THROW ( Napi::Error::New (env, buf), false );
536+ NAPI_THROW ( FormatError (env , " Expected %d parameters, got %d" , key_count,
537+ list_len),
538+ false );
524539 }
525540
526541 for (int i = 1 ; i <= list_len; i++) {
527542 auto name = sqlite3_bind_parameter_name (handle_, i);
528543 if (name != nullptr ) {
529- snprintf (buf, sizeof (buf) , " Unexpected named param %s at %d" , name, i);
530- NAPI_THROW ( Napi::Error::New (env, buf), false );
544+ NAPI_THROW ( FormatError (env , " Unexpected named param %s at %d" , name, i),
545+ false );
531546 }
532547
533548 auto error = BindParam (env, i, list[i - 1 ]);
534549 if (error != nullptr ) {
535- snprintf (buf, sizeof (buf), " Failed to bind param %d, error %s " , i,
536- error);
537- NAPI_THROW ( Napi::Error::New (env, buf), false );
550+ NAPI_THROW (
551+ FormatError (env, " Failed to bind param %d, error %s " , i, error),
552+ false );
538553 }
539554 }
540555 } else {
@@ -543,18 +558,18 @@ bool Statement::BindParams(Napi::Env env, Napi::Value params) {
543558 for (int i = 1 ; i <= key_count; i++) {
544559 auto name = sqlite3_bind_parameter_name (handle_, i);
545560 if (name == nullptr ) {
546- snprintf (buf, sizeof (buf) , " Unexpected anonymous param at %d" , i);
547- NAPI_THROW ( Napi::Error::New (env, buf), false );
561+ NAPI_THROW ( FormatError (env , " Unexpected anonymous param at %d" , i),
562+ false );
548563 }
549564
550565 // Skip "$"
551566 name = name + 1 ;
552567 auto value = obj[name];
553568 auto error = BindParam (env, i, value);
554569 if (error != nullptr ) {
555- snprintf (buf, sizeof (buf), " Failed to bind param %s, error %s " , name,
556- error);
557- NAPI_THROW ( Napi::Error::New (env, buf), false );
570+ NAPI_THROW (
571+ FormatError (env, " Failed to bind param %s, error %s " , name, error),
572+ false );
558573 }
559574 }
560575 }
0 commit comments