【问题标题】:How to handle java exception in user friendly way如何以用户友好的方式处理java异常
【发布时间】:2011-04-24 07:12:18
【问题描述】:

我正在开发一个 Swing 应用程序,我有点困惑如何处理异常,例如最近我的代码重命名文件的一部分,所以当我测试它时,我想出了一个“你没有重命名文件的权限”,因为我从打印异常消息中得到它。那么我该如何向用户表达这个信息呢?我应该使用 JOptionPane 消息还是只在状态栏上显示它?

谢谢

【问题讨论】:

    标签: java swing exception exception-handling


    【解决方案1】:

    从您的问题看来,您已经知道如何处理 Java 意义上的异常。但是,您正在寻找有关如何在捕获异常后对其做出反应的建议。

    在您在问题中给出的具体示例中,我(作为用户)希望非常清楚地显示该错误,因此 JOptionPane 可能是您最好的选择。我不会只更新状态栏,因为这非常接近于静默失败,用户只会感到困惑。

    个人的经验法则是,如果用户在继续他们的任务之前可能要等待代码完成,那么他们必须强烈地被告知失败,即一个模态框。如果失败发生在用户可以不关心的后台任务中,或者代码可以从中恢复,或者代码要重试,那么我会使用状态栏或图标更改的更微妙的方法取决于用户界面。

    【讨论】:

    • 谢谢,但还有一点是如何向用户打印最能描述异常的特定消息。我应该打印异常消息吗?
    • 我想这应该取决于异常。如果您相当确定这是一个权限问题,请告诉用户。但是,如果这是您没有预料到的异常(例如堆栈溢出),则显示该异常可能是有意义的
    • 这可能取决于您的用户是谁,他们是否技术?它还取决于错误,在这种特定情况下,错误非常清楚,因此您可能只打印错误文本,在其他情况下......说 NullPointerException......这些对用户没有任何意义,因此您也许应该向他们提供更通俗易懂的解释,并指示他们检查日志或与公司服务台交谈。
    【解决方案2】:

    详细说明 Kevin D 的评论 - 这实际上取决于您的预期用户受众。如果他们技术熟练,您可以按原样使用异常文本。如果不是,那么我会在消息前面加上“发生错误,请与您的技术支持人员联系并提供以下信息:”然后附加错误消息,最好是一个唯一标识符,用于定位相关的日志条目......我经常使用时间戳。

    如果您真的想变得花哨,您可以通过电子邮件向技术支持人员发送更多详细信息,例如异常和完整堆栈跟踪、日志条目副本等。我过去曾这样做过,但您必须小心,因为一个经常发生的错误会很快淹没一个收件箱:)

    当然,如果用户可以修复错误,那么您可以在消息中说明(以及如何执行)。这是你能得到的最彻底和最花哨的……

    【讨论】:

      【解决方案3】:

      我不太明白你问题的第一部分,但我尝试回答第二部分。通常,您希望如何向用户显示错误取决于软件和错误。在大多数情况下,JOptionPane 或类似名称是合适的。但是,在某些情况下,模态对话框可能过于打扰,而状态栏可能是更好的选择。但同样,这取决于您编写的软件类型。

      【讨论】:

        【解决方案4】:

        如果您预计用户操作可能会导致异常发生,那么您应该在有意义的地方明确捕获它并确保您的程序正确恢复。

        例如,如果用户可以重命名文件,您可以调用 rename() 方法,该方法返回状态代码以指示成功或失败错误代码。在方法内部,这些代码之一实际上可能由异常触发,但调用代码并不关心。调用返回后,状态码可用于确定显示哪个错误消息(如果有)。

          enum RenameStatus {
            Success,
            Failed,
            SecurityFailed
          }
        
          void doRename(File fromFile, File toFile) {
             switch (rename(fromFile, toFile)) {
             case Success:
               break;
             case Failed:
               // todo generic dialog rename operation failed
               break;
             case SecurityFailed:
               // todo security dialog rename operation failed due to permission
               break;
             }
          }
        
          RenameStatus rename(File fromFile, File toFile) {
            try {
              if (!fromFile.renameTo(toFile)) {
                return RenameStatus.Failed;
              }
              return RenameStatus.Success;
            }
            catch (SecurityException e) {
              // Error - permission error
              return RenameStatus.SecurityFailed;
            }
            catch (Exception e) {
              return RenameStatus.Failed;
            }
          }
        

        【讨论】:

        • 恐怕这不能回答 OP 的问题。
        【解决方案5】:

        如果您捕获了表达式(包含在 try-catch- 块中),您会在发生此异常时收到通知。然后你必须决定:有没有办法让事情重新开始?例如,您能否要求用户提供另一个文件名?那就这样做吧!但是如果没有合理的方法来规避错误,那么就让程序中止。

        【讨论】:

        • 这并没有回答关于“如何向用户通知异常”的问题。
        【解决方案6】:

        文件权限是一种“正常”异常,而不是像“磁盘已满”那样的真正“异常”,因此您可能只使用JOptionPane 而不是发送错误报告。话虽如此,一些较早的答案提供了非常丰富的信息,应该在一般情况下采用。

        另外,我的main()总是这样开头的:

        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()
        {
             public void uncaughtException(Thread t, Throwable e)
             {
                 // do your things: see earlier answers
             }
        }
        

        【讨论】:

          【解决方案7】:

          使用 Try-Catch 处理...

          http://tutorials.jenkov.com/java-exception-handling/basic-try-catch-finally.html

          当你捕捉到异常时,你可以对它做任何你想做的事情。将其显示给用户,在代码中执行其他操作,根据异常向用户显示另一条消息等。

          【讨论】:

          • 问题不是“如何捕获异常?”但是“如何在我的 GUI 中向用户显示异常?”。
          • 但这就是 OP 的要求!
          • @Jason S - 看看标题。 “以用户友好的方式”确实意味着 OP 已经知道如何捕捉它们。
          • @Ishtar:我的评论是针对 Scott 的回答,而不是 Colin 的评论。我们肯定在同一时间发表过评论。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-19
          • 1970-01-01
          • 2015-09-25
          • 1970-01-01
          相关资源
          最近更新 更多