@@ -42,6 +42,10 @@ protected readonly ConcurrentDictionary<int, IJsEngine> _engines
4242 /// Whether this class has been disposed.
4343 /// </summary>
4444 protected bool _disposed ;
45+ /// <summary>
46+ /// The exception that was thrown during the most recent recycle of the pool.
47+ /// </summary>
48+ protected Exception _scriptLoadException ;
4549
4650 /// <summary>
4751 /// Initializes a new instance of the <see cref="JavaScriptEngineFactory"/> class.
@@ -86,7 +90,11 @@ protected virtual IJsPool CreatePool()
8690 poolConfig . StartEngines = _config . StartEngines . Value ;
8791 }
8892
89- return new JsPool ( poolConfig ) ;
93+ var pool = new JsPool ( poolConfig ) ;
94+ // Reset the recycle exception on recycle. If there *are* errors loading the scripts
95+ // during recycle, the errors will be caught in the initializer.
96+ pool . Recycled += ( sender , args ) => _scriptLoadException = null ;
97+ return pool ;
9098 }
9199
92100 /// <summary>
@@ -105,7 +113,7 @@ protected virtual void InitialiseEngine(IJsEngine engine)
105113 LoadUserScripts ( engine ) ;
106114 if ( ! _config . LoadReact )
107115 {
108- // We expect to user to have loaded their own versino of React in the scripts that
116+ // We expect to user to have loaded their own version of React in the scripts that
109117 // were loaded above, let's ensure that's the case.
110118 EnsureReactLoaded ( engine ) ;
111119 }
@@ -127,7 +135,11 @@ private void LoadUserScripts(IJsEngine engine)
127135 }
128136 catch ( JsRuntimeException ex )
129137 {
130- throw new ReactScriptLoadException ( string . Format (
138+ // We can't simply rethrow the exception here, as it's possible this is running
139+ // on a background thread (ie. as a response to a file changing). If we did
140+ // throw the exception here, it would terminate the entire process. Instead,
141+ // save the exception, and then just rethrow it later when getting the engine.
142+ _scriptLoadException = new ReactScriptLoadException ( string . Format (
131143 "Error while loading \" {0}\" : {1}\r \n Line: {2}\r \n Column: {3}" ,
132144 file ,
133145 ex . Message ,
@@ -162,11 +174,12 @@ private static void EnsureReactLoaded(IJsEngine engine)
162174 /// <returns>The JavaScript engine</returns>
163175 public virtual IJsEngine GetEngineForCurrentThread ( )
164176 {
165- EnsureNotDisposed ( ) ;
177+ EnsureValidState ( ) ;
166178 return _engines . GetOrAdd ( Thread . CurrentThread . ManagedThreadId , id =>
167179 {
168180 var engine = _factory ( ) ;
169181 InitialiseEngine ( engine ) ;
182+ EnsureValidState ( ) ;
170183 return engine ;
171184 } ) ;
172185 }
@@ -192,7 +205,7 @@ public virtual void DisposeEngineForCurrentThread()
192205 /// <returns>The JavaScript engine</returns>
193206 public virtual IJsEngine GetEngine ( )
194207 {
195- EnsureNotDisposed ( ) ;
208+ EnsureValidState ( ) ;
196209 return _pool . GetEngine ( ) ;
197210 }
198211
@@ -298,14 +311,20 @@ public virtual void Dispose()
298311 }
299312
300313 /// <summary>
301- /// Ensures that this object has not been disposed.
314+ /// Ensures that this object has not been disposed, and that no error was thrown while
315+ /// loading the scripts.
302316 /// </summary>
303- public void EnsureNotDisposed ( )
317+ public void EnsureValidState ( )
304318 {
305319 if ( _disposed )
306320 {
307321 throw new ObjectDisposedException ( GetType ( ) . Name ) ;
308322 }
323+ if ( _scriptLoadException != null )
324+ {
325+ // This means an exception occurred while loading the script (eg. syntax error in the file)
326+ throw _scriptLoadException ;
327+ }
309328 }
310329
311330 /// <summary>
0 commit comments