无法捕获 MSScriptControl 的 Eval 函数中抛出的自定义异常
Cannot catch custom exception thrown in MSScriptControl's Eval function
这是我的问题的 MVCE。
我有使用 MSScriptControl 动态计算某些公式的方法。
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.
}
}
这是评估员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");
}
}
这是 CustomException class:
using System;
namespace Library
{
public class CustomException : Exception
{
public CustomException()
: base()
{
}
public CustomException(string message)
: base(message)
{
}
}
}
我预计在这种情况下会抛出 CustomException,并且会进入第一个 catch 子句。但是,我得到了一个通用的 Exception
(我使用 GetType().Name
验证了异常类型),而消息是 "Cannot divide by zero"。
尽管如此,我确实在 Evaluator class 中收到以下错误:
An exception of type 'Library.CustomException' occurred in XXX.dll but was not handled in user code
如果我像这样修改我的 DoCalculate() 那么我可以很好地捕获 CustomException:
public void DoCalculate()
{
try
{
var evaluator = new Evaluator();
evaluator.TestThrow();
}
catch (CustomException cex)
{
// Handle CustomException.
}
catch (Exception ex)
{
// Handle general Exception.
}
}
这是否意味着无法从 Eval 函数内部定义和抛出我自己的异常?
我正在使用 .NET 4.6.2 和 Interop.MSScriptControl 1.0.0.0
这是link
中给出的答案的总结
COM 方法通过返回 HRESULTs
来报告错误; .NET 方法通过抛出异常来报告它们。运行时处理两者之间的转换。 .NET Framework 中的每个异常 class 都映射到一个 HRESULT。因此,为了抛出正确的异常,让我提出以下建议。
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;
}
}
这是我的问题的 MVCE。
我有使用 MSScriptControl 动态计算某些公式的方法。
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.
}
}
这是评估员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");
}
}
这是 CustomException class:
using System;
namespace Library
{
public class CustomException : Exception
{
public CustomException()
: base()
{
}
public CustomException(string message)
: base(message)
{
}
}
}
我预计在这种情况下会抛出 CustomException,并且会进入第一个 catch 子句。但是,我得到了一个通用的 Exception
(我使用 GetType().Name
验证了异常类型),而消息是 "Cannot divide by zero"。
尽管如此,我确实在 Evaluator class 中收到以下错误:
An exception of type 'Library.CustomException' occurred in XXX.dll but was not handled in user code
如果我像这样修改我的 DoCalculate() 那么我可以很好地捕获 CustomException:
public void DoCalculate()
{
try
{
var evaluator = new Evaluator();
evaluator.TestThrow();
}
catch (CustomException cex)
{
// Handle CustomException.
}
catch (Exception ex)
{
// Handle general Exception.
}
}
这是否意味着无法从 Eval 函数内部定义和抛出我自己的异常?
我正在使用 .NET 4.6.2 和 Interop.MSScriptControl 1.0.0.0
这是link
中给出的答案的总结COM 方法通过返回 HRESULTs
来报告错误; .NET 方法通过抛出异常来报告它们。运行时处理两者之间的转换。 .NET Framework 中的每个异常 class 都映射到一个 HRESULT。因此,为了抛出正确的异常,让我提出以下建议。
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;
}
}