Skip to content

Commit 5021d39

Browse files
committed
Ensure ExecuteWithLargerStackIfRequired still uses JSON parsing logic if an exception is caught. References #104
1 parent 341f27b commit 5021d39

File tree

5 files changed

+90
-22
lines changed

5 files changed

+90
-22
lines changed

build.proj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ of patent rights can be found in the PATENTS file in the same directory.
1111
<PropertyGroup>
1212
<Major>1</Major>
1313
<Minor>4</Minor>
14-
<Build>0</Build>
14+
<Build>1</Build>
1515
<Revision>0</Revision>
1616
<DevNuGetServer>http://reactjs.net/packages/</DevNuGetServer>
1717
<MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\tools\MSBuildTasks</MSBuildCommunityTasksPath>

src/React.Core/JavaScriptEngineUtils.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
using System;
1111
using JavaScriptEngineSwitcher.Core;
12+
using JavaScriptEngineSwitcher.Core.Helpers;
13+
using Newtonsoft.Json;
1214
using React.Exceptions;
1315

1416
namespace React
@@ -63,5 +65,39 @@ Func<Exception, TException> exceptionFactory
6365
throw new ReactException("Mathematics is broken. 1 + 1 = " + result);
6466
}
6567
}
68+
69+
/// <summary>
70+
/// Calls a JavaScript function using the specified engine. If <typeparamref name="T"/> is
71+
/// not a scalar type, the function is assumed to return a string of JSON that can be
72+
/// parsed as that type.
73+
/// </summary>
74+
/// <typeparam name="T">Type returned by function</typeparam>
75+
/// <param name="engine">Engine to execute function with</param>
76+
/// <param name="function">Name of the function to execute</param>
77+
/// <param name="args">Arguments to pass to function</param>
78+
/// <returns>Value returned by function</returns>
79+
public static T CallFunctionReturningJson<T>(this IJsEngine engine, string function, params object[] args)
80+
{
81+
if (ValidationHelpers.IsSupportedType(typeof(T)))
82+
{
83+
// Type is supported directly (ie. a scalar type like string/int/bool)
84+
// Just execute the function directly.
85+
return engine.CallFunction<T>(function, args);
86+
}
87+
// The type is not a scalar type. Assume the function will return its result as
88+
// JSON.
89+
var resultJson = engine.CallFunction<string>(function, args);
90+
try
91+
{
92+
return JsonConvert.DeserializeObject<T>(resultJson);
93+
}
94+
catch (JsonReaderException ex)
95+
{
96+
throw new ReactException(string.Format(
97+
"{0} did not return valid JSON: {1}.\n\n{2}",
98+
function, ex.Message, resultJson
99+
));
100+
}
101+
}
66102
}
67103
}

src/React.Core/ReactEnvironment.cs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -231,26 +231,7 @@ public virtual T Execute<T>(string function, params object[] args)
231231
{
232232
try
233233
{
234-
if (ValidationHelpers.IsSupportedType(typeof (T)))
235-
{
236-
// Type is supported directly (ie. a scalar type like string/int/bool)
237-
// Just execute the function directly.
238-
return Engine.CallFunction<T>(function, args);
239-
}
240-
// The type is not a scalar type. Assume the function will return its result as
241-
// JSON.
242-
var resultJson = Engine.CallFunction<string>(function, args);
243-
try
244-
{
245-
return JsonConvert.DeserializeObject<T>(resultJson);
246-
}
247-
catch (JsonReaderException ex)
248-
{
249-
throw new ReactException(string.Format(
250-
"{0} did not return valid JSON: {1}.\n\n{2}",
251-
function, ex.Message, resultJson
252-
));
253-
}
234+
return Engine.CallFunctionReturningJson<T>(function, args);
254235
}
255236
catch (JsRuntimeException ex)
256237
{
@@ -381,7 +362,7 @@ public virtual T ExecuteWithLargerStackIfRequired<T>(string function, params obj
381362
var engine = _engineFactory.GetEngineForCurrentThread();
382363
try
383364
{
384-
result = engine.CallFunction<T>(function, args);
365+
result = engine.CallFunctionReturningJson<T>(function, args);
385366
}
386367
catch (Exception threadEx)
387368
{
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2015, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
using JavaScriptEngineSwitcher.Core;
11+
using Moq;
12+
using NUnit.Framework;
13+
using React.Exceptions;
14+
15+
namespace React.Tests.Core
16+
{
17+
[TestFixture]
18+
public class JavaScriptEngineUtilsTests
19+
{
20+
[Test]
21+
public void CallFunctionReturningJsonHandlesScalarReturnValue()
22+
{
23+
var engine = new Mock<IJsEngine>();
24+
engine.Object.CallFunctionReturningJson<int>("hello");
25+
engine.Verify(x => x.CallFunction<int>("hello"));
26+
}
27+
28+
[Test]
29+
public void CallFunctionReturningJsonHandlesJson()
30+
{
31+
var engine = new Mock<IJsEngine>();
32+
engine.Setup(x => x.CallFunction<string>("hello")).Returns("{\"message\":\"Hello World\"}");
33+
var result = engine.Object.CallFunctionReturningJson<Example>("hello");
34+
Assert.AreEqual("Hello World", result.Message);
35+
}
36+
37+
[Test]
38+
public void CallFunctionReturningJsonThrowsOnInvalidJson()
39+
{
40+
var engine = new Mock<IJsEngine>();
41+
engine.Setup(x => x.CallFunction<string>("hello")).Returns("lol wut this is not json '\"");
42+
Assert.Throws<ReactException>(() => engine.Object.CallFunctionReturningJson<Example>("hello"));
43+
}
44+
45+
private class Example
46+
{
47+
public string Message { get; set; }
48+
}
49+
}
50+
}

src/React.Tests/React.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
</Compile>
9898
<Compile Include="Core\FileCacheHashTests.cs" />
9999
<Compile Include="Core\JavaScriptEngineFactoryTest.cs" />
100+
<Compile Include="Core\JavaScriptEngineUtilsTests.cs" />
100101
<Compile Include="Core\JsxTransformerTests.cs" />
101102
<Compile Include="Core\ReactComponentTest.cs" />
102103
<Compile Include="Mvc\HtmlHelperExtensionsTests.cs" />

0 commit comments

Comments
 (0)