从 ClearScript 调用时在 JScript 中捕获 Adwords 错误?
Trapping Adwords errors in JScript when called from ClearScript?
上下文:VS2015 社区; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0
有关此帖子的背景,请参阅 (顺便说一句,感谢@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
运行 中可用的常用数据没有存储在我能看到的任何地方。
我确实尝试使用
投射变异的结果
response = host.cast(BudgetOrderReturnValue,bos.mutate(mutations));
但是出现错误时,response
仍然设置为undefined。
我已经能够为指定的变异捕获 XML
<add name="AdsClientLibs.DetailedRequestLogs" value="All" />
in App.config
这给了我 detailed_logs.log
in 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>
但是,none 的数据似乎可供脚本使用。
想法,有人吗?
稍后
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");
}
//...
}
不幸的是,这不起作用。 bos.mutate 行导致脚本因未捕获的错误而崩溃。
第二天
EXE 运行 脚本的输出:
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;
})
C#代码
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);
}
JScript代码如上。所以 ClearScript 引擎似乎不能很好地处理 tryCatch。
几天后
我至少从中学到了一件事:我不需要把
WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging
在实例化 JScriptEngine
对象时添加到我的 C# 代码中。如果脚本中有 debugger;
语句,系统会提示我启动调试会话。
但回到脚本
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;
}
第一次通过,效果不错。第二次,日期不变,引发 AdWords 错误(日期范围已采用),导致 JScriptEngine 引发未处理的异常错误。我收到启动调试会话的提示,该会话在启动时显示一个包含
的对话框
Unhandled exception at line 52, column 2 in JScript - script block
0x8013baff - unknown exception
和行上的突出显示 response = bos.mutate(mutations);
。无论我是否有 debugger;
声明,都会发生这种情况。
所以我放弃了使用 ClearScript 编写 AdWords 脚本。也许我应该将此作为错误提交给 ClearScript 的人员。
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)) { ... }
...
}
显然,要使其正常工作,您必须通过 ScriptEngine.AddHostType
.
公开主机异常类型(BudgetOrderError
等)
上下文:VS2015 社区; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0
有关此帖子的背景,请参阅
我现在有一个通过 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
运行 中可用的常用数据没有存储在我能看到的任何地方。
我确实尝试使用
投射变异的结果response = host.cast(BudgetOrderReturnValue,bos.mutate(mutations));
但是出现错误时,response
仍然设置为undefined。
我已经能够为指定的变异捕获 XML
<add name="AdsClientLibs.DetailedRequestLogs" value="All" />
in App.config
这给了我 detailed_logs.log
in 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>
但是,none 的数据似乎可供脚本使用。
想法,有人吗?
稍后
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");
}
//...
}
不幸的是,这不起作用。 bos.mutate 行导致脚本因未捕获的错误而崩溃。
第二天
EXE 运行 脚本的输出:
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;
})
C#代码
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);
}
JScript代码如上。所以 ClearScript 引擎似乎不能很好地处理 tryCatch。
几天后
我至少从中学到了一件事:我不需要把
WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging
在实例化 JScriptEngine
对象时添加到我的 C# 代码中。如果脚本中有 debugger;
语句,系统会提示我启动调试会话。
但回到脚本
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;
}
第一次通过,效果不错。第二次,日期不变,引发 AdWords 错误(日期范围已采用),导致 JScriptEngine 引发未处理的异常错误。我收到启动调试会话的提示,该会话在启动时显示一个包含
的对话框Unhandled exception at line 52, column 2 in JScript - script block
0x8013baff - unknown exception
和行上的突出显示 response = bos.mutate(mutations);
。无论我是否有 debugger;
声明,都会发生这种情况。
所以我放弃了使用 ClearScript 编写 AdWords 脚本。也许我应该将此作为错误提交给 ClearScript 的人员。
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)) { ... }
...
}
显然,要使其正常工作,您必须通过 ScriptEngine.AddHostType
.
BudgetOrderError
等)