Kontext: VS2015 Gemeinschaft; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0Überfüllung von AdWords-Fehlern in JScript beim Aufruf aus ClearScript?
Hintergrundinformationen zu diesem Beitrag finden Sie eine earlier posting (Kudos, nebenbei gesagt, für die Lösung des ersten Rätsels @BitCortex.)
Ich habe jetzt eine funktionierende Skript Adwords Mutation in JScript über ClearScript und C#. Die Herausforderung besteht nun darin, Fehler zu behandeln.
Im folgenden Stück Code, Ich erstelle eine neue 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;
}
Das Problem, das ich im Moment habe, ist, dass, wenn es ein Fehler ist, exc
nicht sinnvoll, alles hat in ihm von
exc
{...}
description: ""
message: ""
name: "Error"
number: -2146190593
zum Beispiel, und response
ist undefinierten.
Die üblichen Daten, die in einer BudgetOrderReturnValue
in nativ in C# verfügbar wäre, wird nicht gespeichert, wo ich sehen kann.
Ich habe versucht, das Ergebnis des mutieren Gießen
response = host.cast(BudgetOrderReturnValue,bos.mutate(mutations));
verwenden, aber wenn der Fehler auftritt, wird response
noch als undefined gesetzt.
ich in der Lage habe die XML für die mutieren zu erfassen
<add name="AdsClientLibs.DetailedRequestLogs" value="All" />
in App.config
angegeben zu haben, die mir in C:\Logs\Adwords
ein detailed_logs.log
gibt. Wenn ein Fehler auftritt, bin ich daher in der Lage, zu diesem Protokoll zurückzukehren und zu sehen, um welchen Fehler es sich handelt, z.
<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>
jedoch keine dieser Daten scheint das Skript zur Verfügung zu stehen.
Ideen, jemand?
SPÄTER
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");
}
//...
}
Leider ist dies nicht funktioniert. Die Bos.Mutate-Zeile führt zum Absturz des Skripts mit einem nicht erfassten Fehler.
NÄCHSTEN TAG
Die Ausgabe aus dem EXE läuft das Skript:
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;
})
Der C# -Code
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);
}
Der JScript-Code, wie oben. Daher scheint die ClearScript-Engine mit tryCatch nicht gut zu sein.
Ein paar Tage später
ich eine Sache, zumindest aus diesem gelernt habe: Ich
WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging
in meinen C# -Code nicht setzen müssen, wenn das JScriptEngine
Objekt instanziieren . Wenn im Skript eine debugger;
-Anweisung vorhanden ist, werde ich aufgefordert, eine Debugsitzung zu starten.
Aber zurück zum Skript
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;
}
Das erste Mal durch, es funktioniert gut. Beim zweiten Mal, bei unveränderten Datumsangaben, wird ein AdWords-Fehler (Datumsbereich bereits vergeben) ausgelöst, der dazu führt, dass JScriptEngine einen unbehandelten Ausnahmefehler auslöst. Ich werde aufgefordert, eine Debug-Sitzung zu starten, die beim Start einen Dialog
Unhandled exception at line 52, column 2 in JScript - script block
0x8013baff - unknown exception
und das Highlight auf der Linie response = bos.mutate(mutations);
enthält, zeigt. Und das passiert, ob ich eine debugger;
Erklärung habe oder nicht.
Also gebe ich die Skripterstellung von AdWords mit ClearScript auf. Vielleicht sollte ich dies bei ClearScript als Fehler bei den Leuten ablegen.
Seltsam. Für mich ist die 'debugger'-Anweisung nichts, wenn ich nicht das Skript-Debugging über' WindowsScriptEngineFlags 'aktiviere. Wenn Sie diese nicht behandelte Ausnahme in einem Skriptdebugger (Visual Studio?) Sehen, ist es wahrscheinlich in Ordnung. Die Hostausnahme wird aus der Sicht der Skriptsteuerkomponente nicht behandelt, aber wenn Sie die Ausführung fortsetzen, fängt der Host sie ab und gibt sie an Ihre Handlerfunktion weiter. Ihre Handler-Funktion gibt 'true' zurück und weist ClearScript an, die Ausnahme nicht erneut auszulösen, damit kein Absturz außerhalb des Debuggers auftritt. So soll es funktionieren. – BitCortex