Java:我们通常不希望向用户显示错误堆栈跟踪中的哪些信息? [英] Java: what information in error stack trace do we typically not wish to show users?

查看:119
本文介绍了Java:我们通常不希望向用户显示错误堆栈跟踪中的哪些信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是java的新手,我不熟悉错误堆栈跟踪在抛出并随后显示给我的Web应用程序的最终用户时使用的格式规则。

I'm new to java and I'm not that familiar with the formatting rules used by an error stack trace when it is thrown and subsequently displayed to an end-user of my web application.

我对Oracle数据库的体验是错误堆栈包含内部信息,例如模式和过程名称以及行号,虽然对于调试很有用,但是想阻止用户看到。这是一个例子:

My experience with Oracle database is that the error stack contains internal information, such as schema and procedure names and line number(s), which, while useful for debugging, I would like to prevent the user from seeing. Here's an example:

java.sql.SQLException : ORA-20011: Error description here
ORA-07894: at "NAME_OF_SCHEMA.PROCEDURE_NAME", line 121
ORA-08932: at line 10

字符串我想向用户显示这里的错误描述。我可以使用正则表达式提取此字符串,因为我知道(1)此字符串始终位于第一行,因此我可以提取错误堆栈跟踪的第一行,以及(2)此字符串始终以错误并以行尾结束。 [注意Oracle用户(我不想误导你):以上仅适用于RAISE_APPLICATION_ERROR,错误字符串以错误开头,否则文本错误不存在]。

The string I want to display to user is Error description here. I can extract this string using regex expressions because I know (1) this string is always on the first line, so I can extract the first line of the error stack trace, and (2) this string always begins with Error and ends with the end of the line. [Note for Oracle users (I don't want to mislead you): the above only applies when using RAISE_APPLICATION_ERROR with an error string starting with Error, otherwise the text Error is not there].

我对Java的问题是:

My questions for Java are:

(1)您是否有任何潜在的敏感信息,您不希望用户在错误堆栈中看到?如果是这样,什么?例如,文件路径,服务器名称/ IP等。

(1) Is there anything potentially sensitive that you wouldn't want users to see in the error stack? If so, what? For example, file paths, server name/IP, etc.

(2)是否有任何格式规则可以依赖Java错误堆栈跟踪来提取非敏感信息?或者,其他人如何解决这个问题?

(2) Are there any formatting rules for the Java error stack trace that I can rely on to extract the non-sensitive information? Or, how to others address this concern?

更新1:

感谢所有回复,他们非常乐于助人。虽然许多人评论使用诸如 getUserFriendlyMessage()之类的函数来将错误映射到有用的用户消息,但我想知道是否有人可以扩展此映射。也就是说,对于常见错误(SQL,I / O等),可以使用什么可靠标识符来搜索此错误堆栈以识别发生的错误类型,然后推荐相应的文本字符串映射到此错误消息以显示给用户? @ Adarshr的回复是一个好的开始。例如,

Thanks for all the replies so far, they've been very helpful. While many people comment to use a function such as getUserFriendlyMessage() to map errors to useful user messages, I wonder if someone could expand on this mapping. That is, for the common errors (SQL, I/O, etc.), what "reliable" identifier could be used to search this error stack for to identify the type of error that happened, and then what corresponding text string would you recommend to map to this error message to show to the user? @Adarshr's response below is a good start. For example,

Identified Expected   If found in error stack, display this friendly msg to user
-------------------   ----------------------------------------------------------
SQLException          An error occurred accessing the database. Please contact support at support@companyname.com.
IOException           Connection error(?). Please check your internet connection.

假设编译相关的错误不需要解决,而是关注最终用户可能会遇到的错误正常使用期间的经验。作为参考,这里是运行时错误消息的列表: http://mindprod.com/jgloss/ runerrormessages.html#IOEXCEPTION

Assume compile-related errors don't need to addressed, but rather focus those errors that end users might experience during normal use. For reference, here's a list of run-time error messages: http://mindprod.com/jgloss/runerrormessages.html#IOEXCEPTION

或者,是否可以使用堆栈跟踪的第一行显示给用户?这个链接就像我在上面的原始问题中得到的那样:

Alternatively, is it possible to just use the FIRST LINE of the stack trace to display to user? This link is sort of what I was getting at in my original question above:

http://www3.ntu.edu.sg/home/ehchua/programming/howto/ErrorMessages.html

例如,如果始终使用标识符 Exception ,则可以简单地提取 Exception之间的文本和第一行的结尾。我不知道我们是否可以依赖 Exception 总是在那里。

For example, if the identifier Exception is always used, one could simply extract the text that comes between Exception and the end of the first line. I don't know if we can rely on Exception always being there.

推荐答案

您不应该向您的用户展示任何gobbledygook。它对大多数人来说毫无意义,对你没有帮助。正如您所怀疑的那样,它还会暴露您的实施内部可能暗示恶意用户可能会使用的漏洞。

You shouldn't show any of that gobbledygook to your users. It's meaningless to most of them and doesn't help you. As you suspect, it also exposes internals of your implementation that may suggest vulnerabilities that a malicious user might be able to use.

相反,您应该捕获异常,记录它们,并向您的用户显示更易于理解的错误消息。您可以使用 getMessage()来提取异常的消息部分。如果异常没有消息,则显示无可用详细信息之类的内容。

Instead, you should catch exceptions, log them, and show a more comprehensible error message to your users. You can use getMessage() to extract the message part of an exception. If the exception has no message, then show something like "no details available".

更新:

I根据问题更新得到一些评论。首先,我会完全将用户与系统的任何内部隔离,既要善待用户,又要保证安全。 (例如,即使知道您正在使用java.sql包,也可能会向聪明的黑客提出漏洞。)因此,在向用户显示任何内容时,请不要使用异常消息,堆栈跟踪的第一行或类似的内容。 。

I have some comments based on the question update. First, I would totally insulate the user from any of the internals of your system, both to be kind to the user and for security. (For instance, even knowing that you are using the java.sql package may suggest vulnerabilities to a clever hacker.) So do not use the exception message, the first line of the stack trace, or anything like that when displaying anything to the user.

其次,您应该将所有错误从异常级别(他们在您的代码中经历)映射到处于适当抽象级别的消息。用户。正确的方法取决于系统的内部以及用户在引发异常时可能尝试做的事情。这可能意味着将系统结构化为层,以便捕获异常的每个层将其转换为更高抽象层的异常。 Java异常可以包装另一个异常(原因)。例如:

Second, you should be mapping all errors from the exception level (at which they are experienced in your code) to messages that are at the right level of abstraction for the user. The proper way to do that would depend on the internals of your system and what the user might have been trying to do when the exception was raised. This might mean structuring your system into layers such that each layer that catches an exception translates it into an exception at a higher layer of abstraction. A Java exception can wrap another exceptions (the cause). For instance:

public boolean copyFile(File source, File destination) throws CopyException {
    try {
        // lots of code
        return true;
    } catch (IOException e) {
        throw new CopyException("File copy failed", e);
    }
}

然后可以在更高级别使用用户类:

Then this could be used at a higher level in a User class:

public boolean shareFile(File source, User otherUser) throws ShareException {
    if (otherUser.hasBlocked(this) {
        throw new ShareException("You cannot share with that user.");
    }
    try {
        return copyFile(source, otherUser.getSharedFileDestination(source));
    } catch (CopyException e) {
        throw new ShareException("Sharing failed due to an internal error", e);
    }
}

(我希望上面的代码清楚地表明将异常转换为更高级别的抽象的想法,而不是作为建议您应该在系统中使用的代码。)

(I hope it's clear that the above code is meant to illustrate the idea of converting exceptions to higher levels of abstraction, not as a suggestion for code that you should use in your system.)

您想要处理这样的事情(而不是以某种方式按摩消息和/或堆栈跟踪)的原因是异常(例如,带有m的IOException)消息权限被拒绝)可能对用户(以及您的系统)在不同情况下的意义完全不同。

The reason that you want to handle things like this (instead of somehow massaging the message and/or stack trace) is that an exception (for instance an IOException with message "permission denied") may mean totally different things to the user (and to your system) in different contexts.

这篇关于Java:我们通常不希望向用户显示错误堆栈跟踪中的哪些信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆