@@ -187,51 +187,86 @@ void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
187187 args.GetReturnValue ().Set (enabled);
188188}
189189
190- void CryptoErrorVector ::Capture () {
191- clear ();
192- while (auto err = ERR_get_error ()) {
190+ void CryptoErrorStore ::Capture () {
191+ errors_. clear ();
192+ while (const uint32_t err = ERR_get_error ()) {
193193 char buf[256 ];
194194 ERR_error_string_n (err, buf, sizeof (buf));
195- push_back (buf);
195+ errors_. emplace_back (buf);
196196 }
197- std::reverse (begin (), end ());
197+ std::reverse (std:: begin (errors_ ), std:: end (errors_ ));
198198}
199199
200- MaybeLocal<Value> CryptoErrorVector::ToException (
200+ bool CryptoErrorStore::Empty () const {
201+ return errors_.empty ();
202+ }
203+
204+ template <typename ... Args>
205+ void CryptoErrorStore::Insert (const NodeCryptoError error, Args&&... args) {
206+ const char * error_string;
207+ switch (error) {
208+ case NodeCryptoError::CIPHER_JOB_FAILED:
209+ error_string = " Cipher job failed" ;
210+ break ;
211+ case NodeCryptoError::DERIVING_BITS_FAILED:
212+ error_string = " Deriving bits failed" ;
213+ break ;
214+ case NodeCryptoError::ENGINE_NOT_FOUND:
215+ error_string = " Engine \" %s\" was not found" ;
216+ break ;
217+ case NodeCryptoError::INVALID_KEY_TYPE:
218+ error_string = " Invalid key type" ;
219+ break ;
220+ case NodeCryptoError::KEY_GENERATION_JOB_FAILED:
221+ error_string = " Key generation failed" ;
222+ break ;
223+ case NodeCryptoError::NO_ERROR:
224+ error_string = " No error" ;
225+ break ;
226+ }
227+ errors.emplace_back (SPrintF (error_string,
228+ std::forward<Args>(args)...));
229+ }
230+
231+ MaybeLocal<Value> CryptoErrorStore::ToException (
201232 Environment* env,
202233 Local<String> exception_string) const {
203234 if (exception_string.IsEmpty ()) {
204- CryptoErrorVector copy (*this );
205- if (copy.empty ()) copy.push_back (" no error" ); // But possibly a bug...
235+ CryptoErrorStore copy (*this );
236+ if (copy.Empty ()) {
237+ // But possibly a bug...
238+ copy.Insert (NodeCryptoError::NO_ERROR);
239+ }
206240 // Use last element as the error message, everything else goes
207241 // into the .opensslErrorStack property on the exception object.
242+ const std::string& last_error_string = copy.errors_ .back ();
208243 Local<String> exception_string;
209244 if (!String::NewFromUtf8 (
210245 env->isolate (),
211- copy. back (). data () ,
246+ last_error_string ,
212247 NewStringType::kNormal ,
213- copy. back () .size ()).ToLocal (&exception_string)) {
248+ last_error_string .size ()).ToLocal (&exception_string)) {
214249 return MaybeLocal<Value>();
215250 }
216- copy.pop_back ();
251+ copy.errors_ . pop_back ();
217252 return copy.ToException (env, exception_string);
218253 }
219254
220255 Local<Value> exception_v = Exception::Error (exception_string);
221256 CHECK (!exception_v.IsEmpty ());
222257
223- if (!empty ()) {
224- CHECK (exception_v->IsObject ());
225- Local<Object> exception = exception_v.As <Object>();
226- Local<Value> stack;
227- if (!ToV8Value (env->context (), *this ).ToLocal (&stack) ||
228- exception->Set (env->context (), env->openssl_error_stack (), stack)
229- .IsNothing ()) {
230- return MaybeLocal<Value>();
231- }
258+ if (Empty ()) {
259+ return exception_v;
232260 }
233261
234- return exception_v;
262+ CHECK (exception_v->IsObject ());
263+ Local<Object> exception = exception_v.As <Object>();
264+ Local<Value> stack;
265+ if (!ToV8Value (env->context (), *this ).ToLocal (&stack) ||
266+ exception->Set (env->context (), env->openssl_error_stack (), stack)
267+ .IsNothing ()) {
268+ return MaybeLocal<Value>();
269+ }
235270}
236271
237272ByteSource::ByteSource (ByteSource&& other) noexcept
@@ -509,7 +544,7 @@ void ThrowCryptoError(Environment* env,
509544 Local<Object> obj;
510545 if (!String::NewFromUtf8 (env->isolate (), message).ToLocal (&exception_string))
511546 return ;
512- CryptoErrorVector errors;
547+ CryptoErrorStore errors;
513548 errors.Capture ();
514549 if (!errors.ToException (env, exception_string).ToLocal (&exception) ||
515550 !exception->ToObject (env->context ()).ToLocal (&obj) ||
@@ -520,7 +555,7 @@ void ThrowCryptoError(Environment* env,
520555}
521556
522557#ifndef OPENSSL_NO_ENGINE
523- EnginePointer LoadEngineById (const char * id, CryptoErrorVector * errors) {
558+ EnginePointer LoadEngineById (const char * id, CryptoErrorStore * errors) {
524559 MarkPopErrorOnReturn mark_pop_error_on_return;
525560
526561 EnginePointer engine (ENGINE_by_id (id));
@@ -539,14 +574,14 @@ EnginePointer LoadEngineById(const char* id, CryptoErrorVector* errors) {
539574 if (ERR_get_error () != 0 ) {
540575 errors->Capture ();
541576 } else {
542- errors->push_back ( std::string ( " Engine \" " ) + id + " \" was not found " );
577+ errors->Insert (NodeCryptoError::ENGINE_NOT_FOUND, id );
543578 }
544579 }
545580
546581 return engine;
547582}
548583
549- bool SetEngine (const char * id, uint32_t flags, CryptoErrorVector * errors) {
584+ bool SetEngine (const char * id, uint32_t flags, CryptoErrorStore * errors) {
550585 ClearErrorOnReturn clear_error_on_return;
551586 EnginePointer engine = LoadEngineById (id, errors);
552587 if (!engine)
0 commit comments