2016-05-16 8 views
0

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.

+0

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

Antwort

1

JScript hat begrenzte Unterstützung für Host-Ausnahmebehandlung, aber man könnte versuchen 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)) { ... } 
    ... 
} 

Offensichtlich für dies funktioniert muss die Host-Ausnahmetypen (BudgetOrderError et al) über ScriptEngine.AddHostType aussetzen.

+0

Ich gebe das das Häkchen, weil es funktionieren sollte, zumindest was die Dokumentation angeht. Es funktioniert jedoch nicht. Ich bekomme immer noch eine "Unhandled Ausnahme in Zeile 154, Spalte 5 in JScriptEngine/Skript Dokument [temp] .js 0x8013baff - unbekannte Ausnahme" Fehler – bugmagnet

+0

... und der Punkt des Absturzes ist 'response = bos.mutate (Mutationen) ; ' – bugmagnet

+0

Siehst du einen Absturz außerhalb des Debuggers? Wenn ja, sind Sie sicher, dass Ihr Handler (die zweite Funktion, die an "tryCatch" übergeben wurde) "true" zurückgibt? – BitCortex