Skip to content

Commit

Permalink
feat(Promise): Adding userInfo to reject error object (#732)
Browse files Browse the repository at this point in the history
Using System.Exception.Data IDictionary, users can add arbitrary data to a "userInfo" property on the error object.

Fixes #730
  • Loading branch information
rozele committed Oct 5, 2016
1 parent f3f1931 commit 4f089d8
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 58 deletions.
68 changes: 68 additions & 0 deletions ReactWindows/ReactNative.Shared/Bridge/Promise.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Newtonsoft.Json.Linq;
using System;

namespace ReactNative.Bridge
{
class Promise : IPromise
{
private const string DefaultError = "EUNSPECIFIED";

private readonly ICallback _resolve;
private readonly ICallback _reject;

public Promise(ICallback resolve, ICallback reject)
{
_resolve = resolve;
_reject = reject;
}

public void Resolve(object value)
{
if (_resolve != null)
{
_resolve.Invoke(value);
}
}

public void Reject(string code, string message)
{
Reject(code, message, default(Exception));
}

public void Reject(string message)
{
Reject(DefaultError, message, default(Exception));
}

public void Reject(string code, Exception e)
{
Reject(code, e.Message, e);
}

public void Reject(Exception e)
{
if (e == null)
throw new ArgumentNullException(nameof(e));

Reject(DefaultError, e.Message, e);
}

public void Reject(string code, string message, Exception e)
{
if (_reject != null)
{
var errorData = e?.Data;
var userInfo = errorData != null
? JToken.FromObject(errorData)
: null;
_reject.Invoke(new JObject
{
{ "code", code ?? DefaultError },
{ "message", message },
{ "stack", e?.StackTrace },
{ "userInfo", userInfo },
});
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Newtonsoft.Json.Linq;
using ReactNative.Bridge;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -141,63 +142,5 @@ public void Invoke(params object[] arguments)
_instance.InvokeCallback(_id, JArray.FromObject(arguments ?? s_empty));
}
}

class Promise : IPromise
{
private const string DefaultError = "EUNSPECIFIED";

private readonly ICallback _resolve;
private readonly ICallback _reject;

public Promise(ICallback resolve, ICallback reject)
{
_resolve = resolve;
_reject = reject;
}

public void Resolve(object value)
{
if (_resolve != null)
{
_resolve.Invoke(value);
}
}

public void Reject(string code, string message)
{
Reject(code, message, default(Exception));
}

public void Reject(string message)
{
Reject(DefaultError, message, default(Exception));
}

public void Reject(string code, Exception e)
{
Reject(code, e.Message, e);
}

public void Reject(Exception e)
{
if (e == null)
throw new ArgumentNullException(nameof(e));

Reject(DefaultError, e.Message, e);
}

public void Reject(string code, string message, Exception e)
{
if (_reject != null)
{
_reject.Invoke(new JObject
{
{ "code", code ?? DefaultError },
{ "message", message },
{ "stack", e?.StackTrace },
});
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Bridge\JavaScriptModuleRegistration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\JavaScriptModuleRegistry.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\NativeArgumentsParseException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Promise.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\IMessageQueueThread.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\IReactQueueConfiguration.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bridge\Queue\MessageQueueThreadExtensions.cs" />
Expand Down
89 changes: 89 additions & 0 deletions ReactWindows/ReactNative.Tests/Bridge/PromiseTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Newtonsoft.Json.Linq;
using ReactNative.Bridge;
using System;
using System.Threading;

namespace ReactNative.Tests.Bridge
{
[TestClass]
public class PromiseTests
{
[TestMethod]
public void Promise_Resolve()
{
var args = default(object[]);
var are = new AutoResetEvent(false);
var resolve = new MockCallback(a =>
{
args = a;
are.Set();
});
var reject = new MockCallback(_ => { });
var promise = new Promise(resolve, reject);

var o = new object();
promise.Resolve(o);
are.WaitOne();

Assert.IsNotNull(args);
Assert.AreEqual(1, args.Length);
Assert.AreSame(o, args[0]);
}

[TestMethod]
public void Promise_Reject()
{
var args = default(object[]);
var are = new AutoResetEvent(false);
var resolve = new MockCallback(_ => { });
var reject = new MockCallback(a =>
{
args = a;
are.Set();
});
var promise = new Promise(resolve, reject);

var code = "42";
var message = "foo";
promise.Reject(code, message);
are.WaitOne();
Assert.IsNotNull(args);
Assert.AreEqual(1, args.Length);

var json = args[0] as JObject;
Assert.IsNotNull(json);
Assert.AreEqual(code, json["code"]);
Assert.AreEqual(message, json["message"]);
}

[TestMethod]
public void Promise_Reject_UserInfo()
{
var args = default(object[]);
var are = new AutoResetEvent(false);
var resolve = new MockCallback(_ => { });
var reject = new MockCallback(a =>
{
args = a;
are.Set();
});
var promise = new Promise(resolve, reject);

var code = "42";
var message = "foo";
var e = new Exception();
e.Data.Add("qux", "baz");
promise.Reject(code, message, e);
are.WaitOne();

Assert.IsNotNull(args);
Assert.AreEqual(1, args.Length);
var json = args[0] as JObject;
Assert.IsNotNull(json);
var userInfo = json["userInfo"] as JObject;
Assert.IsNotNull(userInfo);
Assert.AreEqual("baz", userInfo["qux"]);
}
}
}
1 change: 1 addition & 0 deletions ReactWindows/ReactNative.Tests/ReactNative.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
</ItemGroup>
<ItemGroup>
<Compile Include="Bridge\PromiseTests.cs" />
<Compile Include="Bridge\ReactInstanceTests.cs" />
<Compile Include="Bridge\NativeModuleBaseTests.cs" />
<Compile Include="Bridge\Queue\MessageQueueThreadTests.cs" />
Expand Down

0 comments on commit 4f089d8

Please sign in to comment.