前两天有个2048游戏的用户反馈说,打开游戏后不能玩儿,只有一个游戏面板,数字无法初始化,更无法移动,设备为iPhone 4S、iOS 5.1。尝试从微信调起Safari打开,依然不好使。由于游戏中运用了比较多的HTML5特性,所以粗略估计是有JS报错导致。不过这样的信息该如何捕获到呢?当然是传说中的window.onerror。
从W3C找到关于window.onerror的方法体介绍:
这个意思,基本可以就是说,window.onerror方法,我们可以写成:
/** * @param {String} errorMessage 错误信息 * @param {String} scriptURI 出错的文件 * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误的详细信息,Anything */ window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { // TODO }
不过使用过程中还得注意兼容性问题,不是所有浏览器都有参数列表中的所有参数,chrome之类的,都是浏览器标准草案的领跑者,这些个参数用就是了!
于是,可以写一个小Demo来尝试一下:
<!DOCTYPE html> <html> <head> <title>Js错误捕获</title> <script type="text/javascript"> /** * @param {String} errorMessage 错误信息 * @param {String} scriptURI 出错的文件 * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误的详细信息,Anything */ window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { console.log("错误信息:" , errorMessage); console.log("出错文件:" , scriptURI); console.log("出错行号:" , lineNumber); console.log("出错列号:" , columnNumber); console.log("错误详情:" , errorObj); } </script> </head> <body> <script type="text/javascript" src="error.js"></script> </body> </html>
其中error.js文件中的内容,简单的这样写一句:
throw new Error("出错了!");
用浏览器跑起来以后,打开console,基本就是这样的了:
所以,这些数据都是可以做上报的了。
当然了,上面的error.js是和html页面同域名下,如果error.js不在同域下,会是怎样的?我们把error.js的引用改一下:
<script type="text/javascript" src="https://doitbegin.duapp.com/error.js"></script>
再来打开console,我们看到的是这样的:
相当于window.onerror方法只捕获到了一个errorMessage,而且是固定字符串,毫无参考价值。查了点资料(Webkit源码),发现在浏览器实现script资源加载的地方,是进行了同源策略判断的,如果是非同源资源,errorMessage就被写死为“Script error”了:
好在script标签有一个crossorigin属性,设置它可以显示比较详细的错误信息,我们试着将script标签改一下:
<script type="text/javascript" src="https://doitbegin.duapp.com/error.js" crossorigin></script>
刷新页面,这个时候看到console中的输出是这样的:
出现这个error也不意外,既然设置了error.js为crossorigin,那error.js的HTTP Response Header也必须设置非同源可访问。为了方便设置Header,把error.js做一个小改动,更名为:error-js.php。
<?php header('Access-Control-Allow-Origin:*'); header('Content-type:text/javascript'); ?> throw new Error('出错了');
此时刷新页面,看到console中的输出就已经正常了,所有信息都能正常捕获:
OK,技术细节分析结束!我2048游戏静态资源是放到静态域(非同源)下的,所以要想通过window.onerror捕获错误信息,就得按照上面的最后一种情况来操作了:
1、添加script的crossorigin属性
2、配置一下服务器,设置静态资源Javascript的Response为Access-Control-Allow-Origin
问题内容: 我在Angular JS接收错误时遇到问题:未捕获的错误:[$ injector:modulerr]。我的JS文件外观 我还包括了angular-route-js Angular文档说问题出在http://docs.angularjs.org/api/ngRoute 问题答案: 尝试添加以下内容:
是否可以使用promises的ES6语法捕获异步错误?例如,以下操作不起作用(.catch未捕获错误): 但是这个同步版本有: 使用try/catch块和清除catch中的错误是执行以下操作的唯一解决方案吗? 对于这个问题,假设抛出错误的代码部分位于另一个命名函数中,因此它没有访问函数的权限。 谢谢 编辑:这里有一个更完整的示例,说明我想在JSFIDLE中做什么。
我无法用axios捕捉错误响应。怎么做?我用的是: 我看到ajax请求的结果有400个状态代码,响应主体看起来像(Django后端)。没关系,我已经准备好在catch处理程序中处理这些错误了。 但是它们转到成功处理程序。为何如此?我在控制台中看到以下输出: 成功处理程序接收axios错误对象作为结果。为什么会这样,下一步该怎么办?此错误对象不包含任何有用信息。 UPD。实际上,错误对象包含有用的信
我还在想方设法搞定PDO。 我有一个用PDO执行的insert语句。插入工作很好,但如果有一个错误,我希望它显示给用户。 我有下面的try catch块。 如果查询失败,或者假设有一个重复的IDNumber,我希望将此显示给用户。 如果我只是尝试回显变量$exception,它是不起作用的。 我想把mysql错误返回给用户。 我一如既往地感谢任何建议。 谢谢,瑞恩 更新 根据建议的答案编写新代码:
我用这些类创建了一个登录名,但给了我一个错误 (!)致命错误:未捕获的错误:调用未定义的方法UserController::c在第17行的C:\xampp\htdocs\progetto个性\控制器\User Controller.php ( ! ) 错误:调用C:\xampp\htdocs\progetOpersonale\controllers\User Controller中未定义的方法Us
我刚刚创建了php web服务器并将其连接到firebase。当我尝试身份验证时,注册工作正常。但问题在于登录。它不断出现以下错误: 致命错误:未捕获错误:调用未定义的方法Kreait\Firebase\Auth::在 /Applications/XAMPP/xamppfiles/htdocs/firebase_series/authActions.php:24Stack跟踪:#0{main}抛出