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



上下文:VS2015社区;C#;明文V8.5.4.5;谷歌广告词.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仍设置为未定义

我已经能够捕获指定突变体的 XML

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

App.config,这让我C:LogsAdwords 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>

但是,脚本似乎都无法使用这些数据。

想法,有人吗?

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

相关内容

  • 没有找到相关文章

最新更新