Cannot catch custom exception thrown in MSScriptControl's Eval function

654 views Asked by At

This is a MVCE of my problem.

I have this method using MSScriptControl to dynamically evaluate some formula.

public void DoCalculate()
{
    try
    {
        var evaluator = new Evaluator();
        IScriptControl ctrl = new ScriptControl();
        ctrl.Language = "JavaScript";
        ctrl.AddObject("Evaluator", evaluator, false);
        var calcFunction = "Number(Evaluator.Divide(4,0))";
        double rs = ctrl.Eval(calcFunction);
    }
    catch (CustomException cex)
    {
        // Handle CustomException.
    }
    catch (Exception ex)
    {
        // Handle general Exception.
    }
}

This is the Evaluator class.

public class Evaluator
{
    public double Divide(int a, int b)
    {
        if (b == 0)
        {
            throw new CustomException("Cannot divide by zero");
        }
        else
        {
            return a / b;
        }
    }

    public void TestThrow()
    {
        throw new CustomException("This is a test");
    }
}

And this is the CustomException class:

using System;

namespace Library
{
    public class CustomException : Exception
    {
        public CustomException()
            : base()
        {
        }

        public CustomException(string message)
            : base(message)
        {
        }
    }
}

I expected that in this case a CustomException will be throw, and the first catch clause will be entered. However, I got an general Exception (I verified the exception type using GetType().Name) with the message "Cannot divide by zero" instead.

I did get the following error in Evaluator class though:

An exception of type 'Library.CustomException' occurred in XXX.dll but was not handled in user code

If I modify my DoCalculate() like this then I can catch a CustomException just fine:

public void DoCalculate()
{
    try
    {
        var evaluator = new Evaluator();
        evaluator.TestThrow();
    }
    catch (CustomException cex)
    {
        // Handle CustomException.
    }
    catch (Exception ex)
    {
        // Handle general Exception.
    }
}

Does that mean it is impossible to define and throw my own exception from inside Eval function?

I'm using .NET 4.6.2 and Interop.MSScriptControl 1.0.0.0

1

There are 1 answers

3
Hasan Emrah Süngü On BEST ANSWER

This is the summary of the answer given in this link

COM methods report errors by returning HRESULTs; .NET methods report them by throwing exceptions. The runtime handles the transition between the two. Each exception class in the .NET Framework maps to an HRESULT. So in order to throw proper exception, Let me suggest the following.

var evaluator = new Evaluator();
IScriptControl ctrl = new MSScriptControl.ScriptControl { Language = "VBScript" };
ctrl.AddObject("Evaluator", new Evaluator(), true);
const string calcFunction = "Evaluator.Divide(4,0)";
try {
    double rs = ctrl.Eval(calcFunction);
}
catch (DivideByZeroException ex) {//Actual DivideByZeroException from .Net
    //How can you divide by zero?!?!
}
catch (Exception ex) {
    //STUFF
}

public class Evaluator {

    public double Divide(int a, int b) {
        if (b == 0) {
            throw new MyDivideByZeroException();
        }
        return a / b;
    }
}

public class MyDivideByZeroException : Exception {

    public MyDivideByZeroException() {
        HResult = -2147352558;
    }
}