您的位置:首页 > 其它

一次难忘的调试经历

2017-01-21 12:53 253 查看
正在编一个网站,在本地编好之后打包成war远程部署到tomcat。在本地一切正常,但是一传到服务器上去就不行了。

我这个网站程序会访问一个网页,去那个网页上爬取点东西,要想爬取就必须需要data.txt提供令牌。

初步锁定bug所在区间,编一个小程序测试一下

@RequestMapping("haha")
@ResponseBody
String debug() {
try {
return Util.debug("SY1606604", "xxxxxx", HttpClients.createDefault());
} catch (IOException e) {
e.printStackTrace();
}
return "error";
}

出错的那段代码原来是Util.login(username,password,client)

我把出错的那段代码重写,写成一个函数叫做Util.debug(),让这个函数返回尽量多的信息

结果



怎么会这样呢?我写了ResponseBody了呀,返回不得是个字符串吗?不会跳到“error”页面的呀。

那我就多返回一点数据:

@RequestMapping("haha")
@ResponseBody
String debug() {
StringBuilder builder = new StringBuilder();
try {
builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
} catch (IOException e) {
builder.append(e.getMessage());
builder.append(e.getCause().toString());
builder.append(e.toString());
builder.append("不可能出错呀");

}
return "error";
}

访问haha页面,结果发现还是上面那种情况,一点都没变啊!

为什么呀?

原来是错中有错,在catch中再次抛出了异常!我又没写finally,结果这个Servlet就向容器抛出异常,结果就跳转到error页面去了!

还有,如果是运行时异常,catch IOException好像不会接住吧,所以改成接一切异常!再加上一个finally

StringBuilder builder = new StringBuilder();
try {
builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
} catch (Exception e) {
builder.append(e.getMessage());
builder.append(e.getCause().toString());
builder.append(e.toString());
builder.append("不可能出错呀");
} finally {
return builder.toString();
}

结果页面中一个字都没有,ctrl+u查看网页源代码,也是空空如也。这tm都是咋回事啊?

要知道上面每一次试错都需要进行

maven package打包

打开tomcat manager页面,undeploy旧的war

选择新的war,点击deploy

等待上传结束,刷新haha页面

每次至少两分钟。

我怒了,我打印了这么多东西为啥一个字都没有?

重定向,接受一切打印!!!!!!!!

@RequestMapping("haha")
@ResponseBody
String debug() {
StringBuilder builder = new StringBuilder();
builder.append("百思不得其解");
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream stream = new PrintStream(out);
try {
System.setErr(stream);
System.setOut(stream);
builder.append(Util.debug("SY1606604", "xxxxx", HttpClients.createDefault()));
} catch (Exception e) {
e.printStackTrace();
} finally {
builder.append(out.toString());
return builder.toString();
}
}

终于:



终于看到了日志,梦寐以求的日志,终于知道自己错在哪里?当我看到找不到data.txt文件这句话时,我差点哭出来,好艰难。

珍惜日志,哪有那么多条件去让你调试、跟踪,根本不可能。连部署都是这么艰难,就像ACM题一样,只告诉你对错bool值,不告诉你错在哪里,这是最令人疯狂的。

仿佛有一个声音不停地在耳边呼喊:“你不行的”,我一直追问:“为什么不行?我哪里不行?”这个声音仿佛在嘲笑:“你为什么不行,我不说”。这就像是彻底的否定。

不断地向别人展示别人无法更改的错误,是一种邪恶。它只是为了指出错误而指出错误,只是无理由的告诉你你不行。这让人如堕深渊。

别人有错误,如果以让其改正为目的,则是善意;如果只是一次简单的评判,则是中意;如果是指出别人错误彰显自己的明智或者羞辱别人,那这就是恶意。

回到上文,这里的错误是找不到data.txt,代码中是这么写的:

OutputStream cout = Files.newOutputStream(Paths.get("src/main/resources/checkcode.jpg"));

路径有问题,因为一旦部署到服务器,就没有这种路径了!应该去掉src/main/resources/这个前缀,因为在maven打包时自动把resources目录下的东西打包到classpath路径中了。更好的解决方法是:使用classPath而不要使用操作系统的文件路径

回头观望,我发现了一种调试程序的手段。

定义一个拦截器,在进行处理请求之前,重定向输出流、错误流或者日志到一个内存流,在请求处理的最后,如果发现错误,则打印这个流。这样就能清楚知道自己错在哪里了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: