这个未知错误来自哪里以及如何防止它?
Where is this unknown error coming from and how to prevent it?
已解决
感谢所有帮助我跟踪此错误的人,使用 Firefox 中的调试器,错误称为 "Error: Exceeded maximum execution time."
希望这个问题可以帮助以后的人。
我希望有人能解释这个未捕获的错误并告诉我如何防止它。
我正在为图书馆开发一个系统,以使用 Google App Script 收集使用情况报告,我们的系统到目前为止已成功将报告发送到 Google 云端硬盘。然而,最近,当我们测试 harvesting all 函数时,控制台中出现了一条未知的错误消息,没有任何指示它是什么类型的错误,并且显示了一条不是来自我们代码的路径。我想知道有没有人遇到过这个错误?有解释吗?以及如何预防?
如果不将报告上传到 Google 驱动器,此代码实际上工作正常,但是一旦我将我的函数与 parser
挂钩并将解析的报告上传到 Google驱动会出现这个错误。
(英语不是我的第一语言,所以如果我的表达造成任何混淆,我很抱歉)
以下是 html 代码:
<!DOCTYPE html>
<html>
<head>
<!--import libraries-->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
/....../(load CSS, scripts)
<div data-role="page" id="main">
/....../(headers, navibar)
<div class='row'>
<div class="column">
<div class='row'>
<h2>Harvest All</h2>
<p>
<button type="submit" class='btn-harvest-vendor'>
<i class="material-icons" id="all">get_app</i>
</button>
</p>
</div>
<div class="column">
<div data-role="link" class="ui-content">
<h2><a id="error-report" href="#error-dialog">Error Report</a></h2>
</div>
</div>
</div>
<div class='row' id='statusTable'>
<h2>Vendor Finder</h2>
<table id="status">
/....../(loading status table with template, I know it's not idea, but I had an issue with using an asynchronous function to create the table back then.)
</table>
</div>
</div>
<!--create error report dialog content-->
<div data-role="page" data-dialog="true" id="error-dialog">
<div data-role="header">
<h1>Error Report</h1>
</div>
<div data-role="main" class="ui-content">
<p id="errors"></p>
</div>
<div data-role="footer">
<h1>Remember to refresh the page for updated status!</h1>
</div>
</div>
<script>
/** determines which function gets called in scripts.html */
$('.btn-harvest-vendor').on('click', btnClassVendor).promise();
$('.btn-retry-report').on('click', btnClassReport).promise();
</script>
</body>
</html>
为了以防万一,我还添加了样式表。
<style>
/* Style the header */
.header {
background-color: #f1f1f1;
padding: 20px;
text-align: center;
}
/* navigation bar style */
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: royalblue;
}
li {
float: left;
}
li a {
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: #117;
}
/* Create three equal columns that floats next to each other */
.column {
float: left;
text-align: center;
width: 33.33%;
}
.column-instruction {
float: left;
text-align: center;
width: 33.33%;
text-align: left;
}
/* Responsive layout - makes the three columns stack on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
.column,.column-instruction {
width: 100%;
}
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
padding: 20px;
}
/* button style */
.btn-harvest-vendor, .btn-retry-report {
background-color: white;
border: none;
color: black;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: pointer;
}
/* table settings */
#myInput {
font-size: 16px; /* Increase font-size */
padding: 12px 20px 12px 40px; /* Add some padding */
}
#status {
border-collapse: collapse; /* Collapse borders */
width: 100%; /* Full-width */
border: 1px solid #ddd; /* Add a grey border */
font-size: 18px; /* Increase font-size */
}
#status th, #status td {
text-align: center; /* center-align text */
padding: 5px; /* Add padding */
}
#status tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#status tr.header, #status tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
.float-right-nav {
float: right;
}
.period {color:red;}
#all {font-size:50px;}
#unsupported {color:red;}
#navi-ref {
text-shadow: none;
color: white;
}
</style>
这就是我调用服务器所做的。收割都是一个没有id的按钮,所以调用这个函数的时候,harvestVendorList
的两个参数都是undefined
。
var btnClassVendor = function(e){
google.script.run.withSuccessHandler(onSuccessVendor).harvestVendorList(e.currentTarget.id,null);
}
并且在服务器中,因为 vendorName
和 type
(harvestVendorList
的参数)都是 undefined
。它将通过供应商列表转到 运行 代码的 else
部分。调用 parseSelect()
后我无法提供任何内容,因为之后将是我队友的代码,我不熟悉这些组件。我知道这还远远不够,但我现在真的无法提供更多信息。如果稍后我可以添加更多详细信息,我会继续在这里发布。现在,如果信息太少,请见谅。
function harvestVendorList(vendorName, type) {
var vendorSpreadsheet = SpreadsheetApp.openByUrl(vendorListUrl).getSheets()[0];
var statusSpreadsheet = SpreadsheetApp.openByUrl(reportStatusUrl).getSheets()[0];
var statusHeaders = statusSpreadsheet.getRange(1, 1, 1, statusSpreadsheet.getLastColumn()).getValues()[0];
var vendorList = ObjApp.rangeToObjects(vendorSpreadsheet.getDataRange().getValues());
var statusList = ObjApp.rangeToObjects(statusSpreadsheet.getDataRange().getValues());
errors = "<p>";
if (vendorName) {
/....../(code for harvesting a vendor or a specific report)
}
else {
for (var i in vendorList) {
Logger.log("harvesting, vendor:" + vendorList[i].vendor);
/** call function to harvest vendor */
harvestVendor(vendorList[i], statusList[i]);
Logger.log(i + " DONE!");
}
}
/....../(code for writing updated status back to the google sheet)
errors += "</p>";
return errors;
}
function harvestVendor(vendor, status) {
var date = new Date();
var year = date.getYear();
var month = date.getMonth();
/** get vendor name for logging error message */
var vendorName = vendor.vendor;
for (var i in vendor) {
if (i != "rowNum" && i != "vendor" && vendor[i]) {
var requestUrl = createURL(vendor[i], year, month);
var reportType = i.toUpperCase();
try {
var data = harvest(requestUrl);
if (data[0] == 0) {
errors += (error messages);
status[i] = 0;
continue;
}
if (data[0] == 3) {
errors+=(error messages);
status[i] = 0;
continue;
}
if (data[0] == 2) {
errors+=(error messages);
status[i] = 0;
continue;
}
}
catch (e) {
errors += (error messages);
continue;
}
status[i] = 1;
/**this is the parsing funcions*/
try {
parseSelect(data[1], vendorName, getPeriod());
}
catch (e) {
errors += (error messages);
status[i] = 2;
continue;
}
/....../(checking exceptions)
/** set 1 sec period between each harvest */
Utilities.sleep(1000);
}
}
status.last = Utilities.formatDate(date, "GMT", "yyyy.MM.dd");
}
function harvest(request) {
var response = UrlFetchApp.fetch(encodeURI(request), { muteHttpExceptions: true });
var content = response.getContentText();
var returnType;
try {
/**checking returning types*/
if(response valid)
returnType=1;
/**response is an array*/
else if(content.substring(0,1) == "[" )
returnType=2
/**response is an object*/
else if(content.substring(0,1)=="{")
returnType=3;
/**if the response is not valid*/
else
returnType=0;
}
/**if any exception happens*/
catch(e){Logger.log(e);}
/**if the response is valid*/
if (returnType > 0)
var data = JSON.parse(content);
Logger.log("return type: " + returnType);
/**store the type and data in an array*/
var result = [returnType, data];
return result;
}
这是错误在控制台中的样子。
Uncaught
Md @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:44
Qe @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:59
(anonymous) @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:6
cg.K @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:86
vd @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:35
rd @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:36
b @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:32
(我知道这很难读,但我只能得到一个 link 的图片,它在最后。)
(错误只是 Uncaught,没有别的,这就是为什么我找不到关于这个错误的任何信息。)
(我的OS是中文所以最后几个字符表示中文OS环境,在英文环境下测试会变成别的。)
这是我从那个未捕获函数的源代码中复制的内容。错误来自 Error(b),我不知道它是什么。
function Md(a, b) {
b = Error(b);
b.name = a;
return b
}
控制台:
更新:
添加withFailureHandler(function(e){console.error(e)}之后,控制台报错变成这样:
After adding failure handler
并且错误来自此 userCodeAppPanel
感谢所有帮助我跟踪此错误的人。
使用 Firefox 中的调试器,错误称为 "Error: Exceeded maximum execution time."
由于某种原因,此错误未显示在 Chrome 控制台中。
另一种跟踪方法是使用视图>执行来跟踪项目中的每个函数运行。
我希望这可以帮助后来在 Google Apps 脚本中遇到相同问题的人。
已解决
感谢所有帮助我跟踪此错误的人,使用 Firefox 中的调试器,错误称为 "Error: Exceeded maximum execution time."
希望这个问题可以帮助以后的人。
我希望有人能解释这个未捕获的错误并告诉我如何防止它。
我正在为图书馆开发一个系统,以使用 Google App Script 收集使用情况报告,我们的系统到目前为止已成功将报告发送到 Google 云端硬盘。然而,最近,当我们测试 harvesting all 函数时,控制台中出现了一条未知的错误消息,没有任何指示它是什么类型的错误,并且显示了一条不是来自我们代码的路径。我想知道有没有人遇到过这个错误?有解释吗?以及如何预防?
如果不将报告上传到 Google 驱动器,此代码实际上工作正常,但是一旦我将我的函数与 parser
挂钩并将解析的报告上传到 Google驱动会出现这个错误。
(英语不是我的第一语言,所以如果我的表达造成任何混淆,我很抱歉)
以下是 html 代码:
<!DOCTYPE html>
<html>
<head>
<!--import libraries-->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
/....../(load CSS, scripts)
<div data-role="page" id="main">
/....../(headers, navibar)
<div class='row'>
<div class="column">
<div class='row'>
<h2>Harvest All</h2>
<p>
<button type="submit" class='btn-harvest-vendor'>
<i class="material-icons" id="all">get_app</i>
</button>
</p>
</div>
<div class="column">
<div data-role="link" class="ui-content">
<h2><a id="error-report" href="#error-dialog">Error Report</a></h2>
</div>
</div>
</div>
<div class='row' id='statusTable'>
<h2>Vendor Finder</h2>
<table id="status">
/....../(loading status table with template, I know it's not idea, but I had an issue with using an asynchronous function to create the table back then.)
</table>
</div>
</div>
<!--create error report dialog content-->
<div data-role="page" data-dialog="true" id="error-dialog">
<div data-role="header">
<h1>Error Report</h1>
</div>
<div data-role="main" class="ui-content">
<p id="errors"></p>
</div>
<div data-role="footer">
<h1>Remember to refresh the page for updated status!</h1>
</div>
</div>
<script>
/** determines which function gets called in scripts.html */
$('.btn-harvest-vendor').on('click', btnClassVendor).promise();
$('.btn-retry-report').on('click', btnClassReport).promise();
</script>
</body>
</html>
为了以防万一,我还添加了样式表。
<style>
/* Style the header */
.header {
background-color: #f1f1f1;
padding: 20px;
text-align: center;
}
/* navigation bar style */
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: royalblue;
}
li {
float: left;
}
li a {
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
background-color: #117;
}
/* Create three equal columns that floats next to each other */
.column {
float: left;
text-align: center;
width: 33.33%;
}
.column-instruction {
float: left;
text-align: center;
width: 33.33%;
text-align: left;
}
/* Responsive layout - makes the three columns stack on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
.column,.column-instruction {
width: 100%;
}
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
padding: 20px;
}
/* button style */
.btn-harvest-vendor, .btn-retry-report {
background-color: white;
border: none;
color: black;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: pointer;
}
/* table settings */
#myInput {
font-size: 16px; /* Increase font-size */
padding: 12px 20px 12px 40px; /* Add some padding */
}
#status {
border-collapse: collapse; /* Collapse borders */
width: 100%; /* Full-width */
border: 1px solid #ddd; /* Add a grey border */
font-size: 18px; /* Increase font-size */
}
#status th, #status td {
text-align: center; /* center-align text */
padding: 5px; /* Add padding */
}
#status tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#status tr.header, #status tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
.float-right-nav {
float: right;
}
.period {color:red;}
#all {font-size:50px;}
#unsupported {color:red;}
#navi-ref {
text-shadow: none;
color: white;
}
</style>
这就是我调用服务器所做的。收割都是一个没有id的按钮,所以调用这个函数的时候,harvestVendorList
的两个参数都是undefined
。
var btnClassVendor = function(e){
google.script.run.withSuccessHandler(onSuccessVendor).harvestVendorList(e.currentTarget.id,null);
}
并且在服务器中,因为 vendorName
和 type
(harvestVendorList
的参数)都是 undefined
。它将通过供应商列表转到 运行 代码的 else
部分。调用 parseSelect()
后我无法提供任何内容,因为之后将是我队友的代码,我不熟悉这些组件。我知道这还远远不够,但我现在真的无法提供更多信息。如果稍后我可以添加更多详细信息,我会继续在这里发布。现在,如果信息太少,请见谅。
function harvestVendorList(vendorName, type) {
var vendorSpreadsheet = SpreadsheetApp.openByUrl(vendorListUrl).getSheets()[0];
var statusSpreadsheet = SpreadsheetApp.openByUrl(reportStatusUrl).getSheets()[0];
var statusHeaders = statusSpreadsheet.getRange(1, 1, 1, statusSpreadsheet.getLastColumn()).getValues()[0];
var vendorList = ObjApp.rangeToObjects(vendorSpreadsheet.getDataRange().getValues());
var statusList = ObjApp.rangeToObjects(statusSpreadsheet.getDataRange().getValues());
errors = "<p>";
if (vendorName) {
/....../(code for harvesting a vendor or a specific report)
}
else {
for (var i in vendorList) {
Logger.log("harvesting, vendor:" + vendorList[i].vendor);
/** call function to harvest vendor */
harvestVendor(vendorList[i], statusList[i]);
Logger.log(i + " DONE!");
}
}
/....../(code for writing updated status back to the google sheet)
errors += "</p>";
return errors;
}
function harvestVendor(vendor, status) {
var date = new Date();
var year = date.getYear();
var month = date.getMonth();
/** get vendor name for logging error message */
var vendorName = vendor.vendor;
for (var i in vendor) {
if (i != "rowNum" && i != "vendor" && vendor[i]) {
var requestUrl = createURL(vendor[i], year, month);
var reportType = i.toUpperCase();
try {
var data = harvest(requestUrl);
if (data[0] == 0) {
errors += (error messages);
status[i] = 0;
continue;
}
if (data[0] == 3) {
errors+=(error messages);
status[i] = 0;
continue;
}
if (data[0] == 2) {
errors+=(error messages);
status[i] = 0;
continue;
}
}
catch (e) {
errors += (error messages);
continue;
}
status[i] = 1;
/**this is the parsing funcions*/
try {
parseSelect(data[1], vendorName, getPeriod());
}
catch (e) {
errors += (error messages);
status[i] = 2;
continue;
}
/....../(checking exceptions)
/** set 1 sec period between each harvest */
Utilities.sleep(1000);
}
}
status.last = Utilities.formatDate(date, "GMT", "yyyy.MM.dd");
}
function harvest(request) {
var response = UrlFetchApp.fetch(encodeURI(request), { muteHttpExceptions: true });
var content = response.getContentText();
var returnType;
try {
/**checking returning types*/
if(response valid)
returnType=1;
/**response is an array*/
else if(content.substring(0,1) == "[" )
returnType=2
/**response is an object*/
else if(content.substring(0,1)=="{")
returnType=3;
/**if the response is not valid*/
else
returnType=0;
}
/**if any exception happens*/
catch(e){Logger.log(e);}
/**if the response is valid*/
if (returnType > 0)
var data = JSON.parse(content);
Logger.log("return type: " + returnType);
/**store the type and data in an array*/
var result = [returnType, data];
return result;
}
这是错误在控制台中的样子。
Uncaught
Md @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:44
Qe @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:59
(anonymous) @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:6
cg.K @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:86
vd @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:35
rd @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:36
b @ 420326566-mae_html_user_bin_i18n_mae_html_user__zh_cn.js:32
(我知道这很难读,但我只能得到一个 link 的图片,它在最后。)
(错误只是 Uncaught,没有别的,这就是为什么我找不到关于这个错误的任何信息。)
(我的OS是中文所以最后几个字符表示中文OS环境,在英文环境下测试会变成别的。)
这是我从那个未捕获函数的源代码中复制的内容。错误来自 Error(b),我不知道它是什么。
function Md(a, b) {
b = Error(b);
b.name = a;
return b
}
控制台:
更新:
添加withFailureHandler(function(e){console.error(e)}之后,控制台报错变成这样:
After adding failure handler
并且错误来自此 userCodeAppPanel
感谢所有帮助我跟踪此错误的人。
使用 Firefox 中的调试器,错误称为 "Error: Exceeded maximum execution time."
由于某种原因,此错误未显示在 Chrome 控制台中。
另一种跟踪方法是使用视图>执行来跟踪项目中的每个函数运行。
我希望这可以帮助后来在 Google Apps 脚本中遇到相同问题的人。