从ClearScript调用时,在JScript中捕获Adwords错误?

时间:2016-05-16 04:18:59

标签: c# google-adwords jscript clearscript

背景:VS2015社区; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0

有关此帖子的背景信息,请参阅earlier posting(顺便提一下,感谢@BitCortex解决第一个难题。)

我现在通过ClearScript和C#在JScript中编写了一个有效的Adwords变种。现在的挑战是处理错误。

在下面的代码块中,我正在创建一个新的BudgetOrder

var order = new BudgetOrder();
order.billingAccountId = acct.id;
order.startDateTime = "20160801 000000 Australia/Perth";
order.endDateTime = "20160831 235959 Australia/Perth";

var amt = new Money();
amt.microAmount = 10000000;
order.spendingLimit = amt;

var boo = new BudgetOrderOperation();
boo.operator = Operator.ADD;
boo.operand = order;
var mutations = ToTypedArray(BudgetOrderOperation, [boo]);

var response;
try {
  response = bos.mutate(mutations);
  Console.WriteLine(response.value[0].billingAccountId);
  Console.WriteLine(response.value[0].id);
  Console.WriteLine(response.value[0].lastRequest.status.ToString());
} catch (exc) {
  Console.WriteLine(exc.message);
}

...

function ToTypedArray(typ, arr) {
  var T;
  if ("string" === typeof typ) {
    T = host.type(typ);
  } else {
    T = typ;
  }
  var a = host.newArr(T, arr.length);
  for (var i = 0; i < arr.length; i++) {
    a.SetValue(arr[i], i);
  }
  return a;
}

我目前遇到的问题是,如果出现错误,exc除了

之外没有任何其他用处
exc
{...}
    description: ""
    message: ""
    name: "Error"
    number: -2146190593
例如,

response 未定义

在C#中本地运行的BudgetOrderReturnValue中可用的常用数据不会存储在我能看到的任何地方。

我确实尝试使用

转换mutate的结果
response = host.cast(BudgetOrderReturnValue,bos.mutate(mutations));  

但是当错误发生时,response仍设置为 undefined

我已经能够捕获指定

的mutate的XML
<add name="AdsClientLibs.DetailedRequestLogs" value="All" />
App.config中的

detailed_logs.log中为C:\Logs\Adwords提供了 <detail> <ns2:ApiExceptionFault xmlns="https://adwords.google.com/api/adwords/cm/v201603" xmlns:ns2="https://adwords.google.com/api/adwords/billing/v201603"> <message>[BudgetOrderError.INVALID_BUDGET_DATE_RANGE @ operations[0].operand.startDateTime.endDateTime; trigger:'Overlapping budget found']</message> <ApplicationException.Type>ApiException</ApplicationException.Type> <errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:BudgetOrderError"> <fieldPath>operations[0].operand.startDateTime.endDateTime</fieldPath> <trigger>Overlapping budget found</trigger> <errorString>BudgetOrderError.INVALID_BUDGET_DATE_RANGE</errorString> <ApiError.Type>BudgetOrderError</ApiError.Type> <ns2:reason>INVALID_BUDGET_DATE_RANGE</ns2:reason> </errors> </ns2:ApiExceptionFault> </detail> 。因此,当发生错误时,我已经能够返回到该日志并查看错误是什么,例如

var response;
var hostException;
var succeeded = host.tryCatch(
    function () {
    response = bos.mutate(mutations);
    return true;
  },
    function (exception) {
    hostException = exception;
    return false;
  });
if (succeeded) {
  // process response
  Console.WriteLine(response.value[0].billingAccountId);
  Console.WriteLine(response.value[0].id);
  Console.WriteLine(response.value[0].lastRequest.status.ToString());

} else {
  // handle host exception
  if (host.isType(BudgetOrderError, hostException)) {
    Console.WriteLine("BudgetOrderException");
  } else if (host.isType(ClientTermsError, hostException)) {
    Console.WriteLine("ClientTermsError");
  }
  //...
}

但是,这些数据似乎都不可用于脚本。

想法,有人吗?

LATER

Exception has been thrown by the target of an invocation.
    at JScript global code (Script Document [temp]:149:0) -> var succeeded = host.tryCatch(
    function () {
    response = bos.mutate(mutations);
    return true;
  },
    function (exception) {
    hostException = exception;
    return false;
  })

不幸的是,这不起作用。 bos.mutate行会导致脚本因未捕获的错误而崩溃。

下一天

运行脚本的EXE的输出:

        string script = File.ReadAllText(scriptSpec);
        try
        {
            answer = JSengine.Evaluate(script);
        }
        catch (ScriptEngineException see)
        {
            Console.WriteLine(see.ErrorDetails);
            ScriptEngineException next = see.InnerException as ScriptEngineException;
            while (next != null)
            {
                Console.WriteLine(next.ErrorDetails);
                next = next.InnerException as ScriptEngineException;
            }
        }
        catch (Exception exc)
        {
            Console.WriteLine(exc.Message);
        }

C#代码

WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging

上面的JScript代码。因此,使用tryCatch时,ClearScript引擎似乎表现不佳。

以后的一段时间

我至少从中学到了一件事:我不需要把

JScriptEngine

在实例化debugger;对象时进入我的C#代码。如果脚本中有 debugger; var CFG = new Config(Path.Combine(Settings.Item("EXEPath"), "mutator2.cfg")); var config = new AdWordsAppConfig(); config.DeveloperToken = CFG.Retrieve("DeveloperToken"); config.UserAgent = CFG.Retrieve("UserAgent"); config.ClientCustomerId = CFG.Retrieve("CustomerID"); config.RetryCount = 10; var user = new AdWordsUser(config); user.OAuthProvider.ClientId = CFG.Retrieve("ClientId"); user.OAuthProvider.ClientSecret = CFG.Retrieve("ClientSecret"); //user.OAuthProvider.AccessToken = CFG.Retrieve("AccessToken"); user.Config.OAuth2RefreshToken = CFG.Retrieve("OAuth2RefreshToken"); try { user.OAuthProvider.RefreshAccessToken(); } catch (ex) { Console.WriteLine("RefreshAccessToken failed."); Environment.Exit(1); } var bos = user.GetService(AdWordsService.v201603.BudgetOrderService); bos = host.cast(BudgetOrderService, bos); //bos.RequestHeader.clientCustomerId = config.ClientCustomerId; //bos.RequestHeader.developerToken = config.DeveloperToken; //bos.RequestHeader.userAgent = config.UserAgent; bas = bos.getBillingAccounts(); var order = new BudgetOrder(); order.billingAccountId = CFG.Retrieve("BillingID"); order.startDateTime = "20160801 000000 Australia/Perth"; order.endDateTime = "20160830 000000 Australia/Perth"; var amt = new Money(); amt.microAmount = 10000000; order.spendingLimit = amt; var boo = new BudgetOrderOperation(); boo.operator = Operator.ADD; boo.operand = order; var mutations = ToTypedArray(BudgetOrderOperation, [boo]); // bos.RequestHeader.validateOnly = true; var response; var hostException; var succeeded = host.tryCatch( function () { response = bos.mutate(mutations); }, function (exception) { hostException = exception; return true; }); if (succeeded) { // process response Console.WriteLine(response.value[0].billingAccountId); Console.WriteLine(response.value[0].id); Console.WriteLine(response.value[0].lastRequest.status.ToString()); } else { // handle host exception if (host.isType(BudgetOrderError, hostException)) { Console.WriteLine("BudgetOrderException"); } else if (host.isType(ClientTermsError, hostException)) { Console.WriteLine("ClientTermsError"); } //... } function qq(v, d) { if (null === v) { return "undefined" === typeof d ? "" : d; } else { return v; } } function ToTypedArray(typ, arr) { var T; if ("string" === typeof typ) { T = host.type(typ); } else { T = typ; } var a = host.newArr(T, arr.length); for (var i = 0; i < arr.length; i++) { a.SetValue(arr[i], i); } return a; } 语句,系统会提示我启动调试会话。

但回到剧本

Unhandled exception at line 52, column 2 in JScript - script block
0x8013baff - unknown exception

第一次通过,它运行正常。第二次,日期不变,抛出AdWords错误(已采用日期范围),导致JScriptEngine抛出未处理的异常错误。我被提示启动一个调试会话,在启动时会显示一个包含

的对话框
response = bos.mutate(mutations);

以及debugger;行上的突出显示。无论我是否有String s = "Thir is a Tiger.\'I like it very nuch!\'I it a pet!"; String s2[] = s.split("\'"); for (int i = 0; i < s2.length; i++) { System.out.println(i+" value "+s2[i]); } 陈述,都会发生这种情况。

所以我放弃使用ClearScript编写AdWords脚本。也许我应该在ClearScript上将这个文件作为民间的错误提交。

1 个答案:

答案 0 :(得分:1)

JScript对主机异常处理的支持有限,但您可以尝试HostFunctions.tryCatch

var hostException;
var succeeded = host.tryCatch(
    function() {
        response = bos.mutate(mutations);
    },
    function(exception) {
        hostException = exception;
        return true;
    }
);
if (succeeded) {
    // process response
    ...
}
else {
    // handle host exception
    if (host.isType(BudgetOrderError, hostException)) { ... }
    else if (host.isType(ClientTermsError, hostException)) { ... }
    ...
}

显然,为了实现这一目标,您必须通过BudgetOrderError公开主机异常类型(ScriptEngine.AddHostType等)。