@@ -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:: beginerrors_ ), std:: enderrors_ ));
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