编写一条没有回溯的简单错误消息 [duplicate]

Write a simple error message without a backtrace [duplicate]

提问人:Timur Shtatland 提问时间:5/15/2023 最后编辑:Timur Shtatland 更新时间:5/18/2023 访问量:196

问:

我想为用户写入一个或一个干净、简单的错误消息,而没有(详细的)回溯。我目前正在使用编写错误消息并退出,如以下简化示例所示:STDOUTSTDERRraise

#!/usr/bin/env ruby

def bar
  raise "this needs to be clean, no backtrace"
end

bar

它将其写入:STDERR

/Users/foo/test/test1.rb:4:in `bar': this needs to be clean, no backtrace (RuntimeError)
        from /Users/foo/test/test1.rb:7:in `<main>'

我只想写这部分:

this needs to be clean, no backtrace 

现实生活中的示例具有更详细的回溯,以及多个语句,用于处理带有自定义消息的不同故障模式。raise

我知道我可以做这样的事情(为了干净),但我想避免重复的代码:STDOUT

puts "this needs to be clean, no backtrace"
raise "this needs to be clean, no backtrace"

相关:

  • Ruby 中未处理的异常 - 这个答案建议了一种比我需要的更复杂的处理异常的方法(即捕获和打印错误消息)。我所需要的只是:(a) - 或类似的东西 - 立即终止程序,以及 (b) 只打印错误消息,而不是全栈跟踪或回溯跟踪,这让我们的用户感到困惑。raise
Ruby 异常 错误处理 退出 回溯

评论

2赞 user229044 5/16/2023
这里的问题是你完全滥用了.例外不是给最终用户看的,它们不是用来与最终用户通信的,它们不会“立即终止程序”。如果你想要这种行为,请编写一个函数,它只是 .raisedie(message)puts message; exit
1赞 user229044 5/16/2023
要点是,异常是一种将控制权从应用程序的一部分传递到另一部分的方法,而不是用于转储错误消息和终止程序。您可以在任何有关该主题的 Ruby 教程中阅读有关异常的更多信息。您遇到的实际问题(打印消息并退出)已由链接的重复项很好地覆盖。
1赞 engineersmnky 5/16/2023
@user229044 对不起,忽略了那部分。添加了另一个帖子,为(b)提供了其他选项。
2赞 engineersmnky 5/16/2023
@TimurShtatland鉴于您已将帖子减少到上面的 (a) 和 (b),我不确定重新提出这个问题是否会增加价值。下面发布和/或链接的答案提供了一个实质性的答案,其中包含有关如何进行的众多选项。 是最直接的和/或终结者,当与abortat_exitKernel#exit
1赞 Arctodus 5/16/2023
我认为没有必要@user229044关闭这个(再次)。该问题与您要链接的问题不完全相同。

答:

2赞 Stefan 5/16/2023 #1

如果你只想输出到 stderr,你可以使用 warn(或直接写入),也许与 exit 一起:$stderr

def bar
  warn "this needs to be clean, no backtrace"
  exit(false)
end

bar

若要更改全局异常处理程序的工作方式,可以注册一个at_exit处理程序,该处理程序检查异常类,打印其消息并使 stdout 静音,以抑制回溯。像这样的东西:

class SimpleError < StandardError ; end

at_exit do
  if $!.is_a?(SimpleError)
    $stderr.puts($!.message)
    $stderr.reopen(IO::NULL)
  end
end

def bar
  raise SimpleError, "this needs to be clean, no backtrace"
end

bar

将这种错误处理设置为可选可能是个好主意。

1赞 Arctodus 5/16/2023 #2

您是否正在尝试重写 Ruby 将未捕获的异常写入 STDERR 的方式?我不知道这是否容易做到(或可取)。

但是,您可以在自定义异常中覆盖回溯,这不会影响其他任何内容。

class ExceptionWithoutBacktrace < StandardError
  def backtrace
    []
  end
end

raise ExceptionWithoutBacktrace, "This should be printed clean"

评论

0赞 Timur Shtatland 5/16/2023
谢谢!很有意思。您提出的解决方案有什么缺点吗?
3赞 Arctodus 5/16/2023
在某些情况下,您实际上希望回溯跟踪可用