Skip to content

Commit

Permalink
Fix exceptions handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nilproject committed Nov 5, 2023
1 parent f2ea242 commit 0dc2e8f
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 13 deletions.
2 changes: 1 addition & 1 deletion NiL.JS/Core/Functions/AsyncFunction.cs
Expand Up @@ -10,7 +10,7 @@ namespace NiL.JS.Core.Functions
[Prototype(typeof(Function), true)]
internal sealed class AsyncFunction : Function
{
private sealed class Сontinuator
internal sealed class Сontinuator
{
private readonly AsyncFunction _asyncFunction;
private readonly Context _context;
Expand Down
14 changes: 13 additions & 1 deletion NiL.JS/Core/GlobalContext.cs
Expand Up @@ -10,6 +10,7 @@
using System.Dynamic;
using System.Threading.Tasks;
using NiL.JS.Backward;
using System.Runtime.ExceptionServices;

namespace NiL.JS.Core
{
Expand Down Expand Up @@ -511,7 +512,18 @@ public JSValue ProxyValue(object value)
Task<JSValue> result;
if (Tools.IsTaskOfT(value.GetType()))
{
result = new Task<JSValue>(() => ProxyValue(value.GetType().GetMethod("get_Result", Type.EmptyTypes).Invoke(value, null)));
result = new Task<JSValue>(() =>
{
try
{
return ProxyValue(value.GetType().GetMethod("get_Result", Type.EmptyTypes).Invoke(value, null));
}
catch (TargetInvocationException e)
{
ExceptionDispatchInfo.Capture(e.InnerException).Throw();
throw;
}
});
}
else
{
Expand Down
7 changes: 5 additions & 2 deletions NiL.JS/ExceptionHelper.cs
Expand Up @@ -12,6 +12,7 @@
using NiL.JS.Statements;
using System.Collections;
using System.Runtime.ExceptionServices;
using NiL.JS.Core.Functions;

namespace NiL.JS
{
Expand All @@ -29,6 +30,7 @@ internal static class ExceptionHelper
typeof(ExceptionHelper),
typeof(ConstructorInfo),
typeof(RuntimeMethodHandle),
typeof(AsyncFunction.Сontinuator),
};

internal sealed class StackTraceState
Expand Down Expand Up @@ -58,8 +60,9 @@ public string ToString(JSException jSException)
{
StackFrame frame = frames[i];
var method = frame.GetMethod();
if (method != null
&& method.GetCustomAttribute(typeof(StackFrameOverrideAttribute)) != null)
if (stack is not null
&& method is not null
&& method.GetCustomAttribute(typeof(StackFrameOverrideAttribute)) != null)
{
stackTraceTexts.RemoveRange(stackTraceTexts.Count - recordsToRemove, recordsToRemove);
recordsToRemove = 0;
Expand Down
17 changes: 9 additions & 8 deletions NiL.JS/Extensions/JSValueExtensions.cs
Expand Up @@ -170,21 +170,22 @@ public static T GetDefinedOr<T>(this JSValue self, T defaultValue)

case TypeCode.Object:
{
if (self is null || self.Value is null)
var value = self.Value;
if (self is null || value is null)
return default(T);

if (self.Value is Function && typeof(Delegate).IsAssignableFrom(typeof(T)))
return ((Function)self.Value).MakeDelegate<T>();
if (value is Function && typeof(Delegate).IsAssignableFrom(typeof(T)))
return ((Function)value).MakeDelegate<T>();

if (typeof(T).IsAssignableFrom(self.Value.GetType()))
return (T)self.Value;

if (typeof(T).IsAssignableFrom(self._oValue.GetType()))
if (self._oValue is not null && typeof(T).IsAssignableFrom(self._oValue.GetType()))
return (T)self._oValue;

if (typeof(T).IsAssignableFrom(value.GetType()))
return (T)value;
try
{
return (T)(Tools.ConvertJStoObj(self, typeof(T), true) ?? self.Value);
return (T)(Tools.ConvertJStoObj(self, typeof(T), true) ?? value);
}
catch (InvalidCastException)
{
Expand Down
2 changes: 1 addition & 1 deletion Tests/Core/Functions/AsyncFunctionTests.cs
Expand Up @@ -43,7 +43,7 @@ public async Task RejectedPromiseShouldBeReturnedAsFaultedTask()
context.Eval("let result = null; async function testAsync() { result = await testAwaitable('test'); }");

var task = context.GetVariable("testAsync").As<Function>().Call(new Arguments()).As<Promise>().Task;
await Assert.ThrowsExceptionAsync<AggregateException>(async () =>
await Assert.ThrowsExceptionAsync<JSException>(async () =>
{
await task;
});
Expand Down

0 comments on commit 0dc2e8f

Please sign in to comment.