2016-05-16 32 views
0

上下文:VS2015社區; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0從ClearScript調用時在JScript中捕獲Adwords錯誤?

有關此公告的背景下,看到一個earlier posting(榮譽,順便說一句,到@BitCortex用於解決第一個難題。)

我現在有一個工作的Adwords突變腳本JScript通過ClearScript和C#。現在的挑戰是處理錯誤。

在下面的代碼塊,我創建一個新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仍設置爲未定義了發生變異的結果。

我已經能夠捕捉到XML對於已經發生變異在App.config指定

<add name="AdsClientLibs.DetailedRequestLogs" value="All" /> 

這使我在C:\Logs\Adwords一個detailed_logs.log。因此,當發生錯誤時,我已能夠回到該日誌並查看錯誤是什麼,例如

 <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> 

但是,沒有任何數據似乎可用於腳本。

想法,任何人?

LATER

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行會導致腳本以未捕獲的錯誤崩潰。

NEXT DAY

從運行腳本的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上表現不佳。

天,一對夫婦LATER

我學會了一件事至少出這一點:實例化JScriptEngine對象時,我並不需要把

WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging 

到我的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中的民衆的一個bug。

+0

奇怪。對我來說''debugger'語句除非通過'WindowsScriptEngineFlags'啓用腳本調試,否則不會執行任何操作。無論如何,如果您在腳本調試器(Visual Studio?)中看到未處理的異常,那麼它可能是好的。宿主異常從腳本引擎的角度來看是未處理的,但是如果你繼續執行,主機會捕獲它並將它傳遞給你的處理函數。你的處理函數返回'true',告訴ClearScript不要重新拋出異常,所以在調試器外面不會看到崩潰。這就是它應該工作的方式。 – BitCortex

回答

1

JScript中有主機異常處理的支持有限,但你可以嘗試HostFunctions.tryCatch:通過ScriptEngine.AddHostType

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等)。

+0

我正在給它打勾,因爲它應該起作用,至少就文檔而言。但是,它不起作用。在JScriptEngine /腳本文檔[temp] .js 0x8013baff - 未知異常「錯誤 – bugmagnet

+0

...,並且崩潰點是響應= bos.mutate(突變)時,我仍然收到了第154行第5列的未處理異常。 ;' – bugmagnet

+0

你在調試器外面看到崩潰嗎?如果是這樣,你確定你的處理程序(第二個函數傳入'tryCatch')是否返回true? – BitCortex