Skip to content

Commit 4f089d8

Browse files
authored
feat(Promise): Adding userInfo to reject error object (microsoft#732)
Using System.Exception.Data IDictionary, users can add arbitrary data to a "userInfo" property on the error object. Fixes microsoft#730
1 parent f3f1931 commit 4f089d8

File tree

5 files changed

+160
-58
lines changed

5 files changed

+160
-58
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using Newtonsoft.Json.Linq;
2+
using System;
3+
4+
namespace ReactNative.Bridge
5+
{
6+
class Promise : IPromise
7+
{
8+
private const string DefaultError = "EUNSPECIFIED";
9+
10+
private readonly ICallback _resolve;
11+
private readonly ICallback _reject;
12+
13+
public Promise(ICallback resolve, ICallback reject)
14+
{
15+
_resolve = resolve;
16+
_reject = reject;
17+
}
18+
19+
public void Resolve(object value)
20+
{
21+
if (_resolve != null)
22+
{
23+
_resolve.Invoke(value);
24+
}
25+
}
26+
27+
public void Reject(string code, string message)
28+
{
29+
Reject(code, message, default(Exception));
30+
}
31+
32+
public void Reject(string message)
33+
{
34+
Reject(DefaultError, message, default(Exception));
35+
}
36+
37+
public void Reject(string code, Exception e)
38+
{
39+
Reject(code, e.Message, e);
40+
}
41+
42+
public void Reject(Exception e)
43+
{
44+
if (e == null)
45+
throw new ArgumentNullException(nameof(e));
46+
47+
Reject(DefaultError, e.Message, e);
48+
}
49+
50+
public void Reject(string code, string message, Exception e)
51+
{
52+
if (_reject != null)
53+
{
54+
var errorData = e?.Data;
55+
var userInfo = errorData != null
56+
? JToken.FromObject(errorData)
57+
: null;
58+
_reject.Invoke(new JObject
59+
{
60+
{ "code", code ?? DefaultError },
61+
{ "message", message },
62+
{ "stack", e?.StackTrace },
63+
{ "userInfo", userInfo },
64+
});
65+
}
66+
}
67+
}
68+
}

ReactWindows/ReactNative.Shared/Bridge/ReactDelegateFactoryBase.cs

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Newtonsoft.Json.Linq;
22
using ReactNative.Bridge;
33
using System;
4+
using System.Collections;
45
using System.Collections.Generic;
56
using System.Linq;
67
using System.Reflection;
@@ -141,63 +142,5 @@ public void Invoke(params object[] arguments)
141142
_instance.InvokeCallback(_id, JArray.FromObject(arguments ?? s_empty));
142143
}
143144
}
144-
145-
class Promise : IPromise
146-
{
147-
private const string DefaultError = "EUNSPECIFIED";
148-
149-
private readonly ICallback _resolve;
150-
private readonly ICallback _reject;
151-
152-
public Promise(ICallback resolve, ICallback reject)
153-
{
154-
_resolve = resolve;
155-
_reject = reject;
156-
}
157-
158-
public void Resolve(object value)
159-
{
160-
if (_resolve != null)
161-
{
162-
_resolve.Invoke(value);
163-
}
164-
}
165-
166-
public void Reject(string code, string message)
167-
{
168-
Reject(code, message, default(Exception));
169-
}
170-
171-
public void Reject(string message)
172-
{
173-
Reject(DefaultError, message, default(Exception));
174-
}
175-
176-
public void Reject(string code, Exception e)
177-
{
178-
Reject(code, e.Message, e);
179-
}
180-
181-
public void Reject(Exception e)
182-
{
183-
if (e == null)
184-
throw new ArgumentNullException(nameof(e));
185-
186-
Reject(DefaultError, e.Message, e);
187-
}
188-
189-
public void Reject(string code, string message, Exception e)
190-
{
191-
if (_reject != null)
192-
{
193-
_reject.Invoke(new JObject
194-
{
195-
{ "code", code ?? DefaultError },
196-
{ "message", message },
197-
{ "stack", e?.StackTrace },
198-
});
199-
}
200-
}
201-
}
202145
}
203146
}

ReactWindows/ReactNative.Shared/ReactNative.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<Compile Include="$(MSBuildThisFileDirectory)Bridge\JavaScriptModuleRegistration.cs" />
3131
<Compile Include="$(MSBuildThisFileDirectory)Bridge\JavaScriptModuleRegistry.cs" />
3232
<Compile Include="$(MSBuildThisFileDirectory)Bridge\NativeArgumentsParseException.cs" />
33+
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Promise.cs" />
3334
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\IMessageQueueThread.cs" />
3435
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\IReactQueueConfiguration.cs" />
3536
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\MessageQueueThreadExtensions.cs" />
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
2+
using Newtonsoft.Json.Linq;
3+
using ReactNative.Bridge;
4+
using System;
5+
using System.Threading;
6+
7+
namespace ReactNative.Tests.Bridge
8+
{
9+
[TestClass]
10+
public class PromiseTests
11+
{
12+
[TestMethod]
13+
public void Promise_Resolve()
14+
{
15+
var args = default(object[]);
16+
var are = new AutoResetEvent(false);
17+
var resolve = new MockCallback(a =>
18+
{
19+
args = a;
20+
are.Set();
21+
});
22+
var reject = new MockCallback(_ => { });
23+
var promise = new Promise(resolve, reject);
24+
25+
var o = new object();
26+
promise.Resolve(o);
27+
are.WaitOne();
28+
29+
Assert.IsNotNull(args);
30+
Assert.AreEqual(1, args.Length);
31+
Assert.AreSame(o, args[0]);
32+
}
33+
34+
[TestMethod]
35+
public void Promise_Reject()
36+
{
37+
var args = default(object[]);
38+
var are = new AutoResetEvent(false);
39+
var resolve = new MockCallback(_ => { });
40+
var reject = new MockCallback(a =>
41+
{
42+
args = a;
43+
are.Set();
44+
});
45+
var promise = new Promise(resolve, reject);
46+
47+
var code = "42";
48+
var message = "foo";
49+
promise.Reject(code, message);
50+
are.WaitOne();
51+
Assert.IsNotNull(args);
52+
Assert.AreEqual(1, args.Length);
53+
54+
var json = args[0] as JObject;
55+
Assert.IsNotNull(json);
56+
Assert.AreEqual(code, json["code"]);
57+
Assert.AreEqual(message, json["message"]);
58+
}
59+
60+
[TestMethod]
61+
public void Promise_Reject_UserInfo()
62+
{
63+
var args = default(object[]);
64+
var are = new AutoResetEvent(false);
65+
var resolve = new MockCallback(_ => { });
66+
var reject = new MockCallback(a =>
67+
{
68+
args = a;
69+
are.Set();
70+
});
71+
var promise = new Promise(resolve, reject);
72+
73+
var code = "42";
74+
var message = "foo";
75+
var e = new Exception();
76+
e.Data.Add("qux", "baz");
77+
promise.Reject(code, message, e);
78+
are.WaitOne();
79+
80+
Assert.IsNotNull(args);
81+
Assert.AreEqual(1, args.Length);
82+
var json = args[0] as JObject;
83+
Assert.IsNotNull(json);
84+
var userInfo = json["userInfo"] as JObject;
85+
Assert.IsNotNull(userInfo);
86+
Assert.AreEqual("baz", userInfo["qux"]);
87+
}
88+
}
89+
}

ReactWindows/ReactNative.Tests/ReactNative.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
9696
</ItemGroup>
9797
<ItemGroup>
98+
<Compile Include="Bridge\PromiseTests.cs" />
9899
<Compile Include="Bridge\ReactInstanceTests.cs" />
99100
<Compile Include="Bridge\NativeModuleBaseTests.cs" />
100101
<Compile Include="Bridge\Queue\MessageQueueThreadTests.cs" />

0 commit comments

Comments
 (0)