2

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

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
duongntbk
  • 620
  • 4
  • 25

1 Answers1

2

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;
    }
}
Hasan Emrah Süngü
  • 3,488
  • 1
  • 15
  • 33
  • It my real code, the CustomException does not actually correspond to any pre-defined .Net exception. But I will try throwing an general Exception with a modified HResult and check for that code to see if an exception is in fact my CustomException. Do you think messing with the HResult of Exception can cause any unwanted effect? – duongntbk Jul 31 '17 at 07:14
  • 1
    Com Exceptions are automatically mapped to .Net exception. If the HResult does not match to pre-defined HResult, then it will be generic com exception. There are many exceptions defined in .Net, I think one of them might match your case, if not. I guess, you have to use `ex.Message` property to find which custom exception it is. I am sorry, I am not quite used to COM interop :( – Hasan Emrah Süngü Jul 31 '17 at 07:36
  • Thank you very much for your help. While I haven't found an exact match, there indeed is some close enough one. The upside is I don't even have to define a CustomException class any more. – duongntbk Jul 31 '17 at 08:15