- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在我最近编写的一个程序中,当我的“业务逻辑”代码在第三方或项目 API 中触发异常时,我想记录下来。 (澄清一下,我想在使用 API 导致异常时记录日志。这可能比实际的 throw
高很多帧,也可能比实际的 catch
低很多帧>(可以记录异常负载的位置。))我做了以下操作:
void former_function()
{
/* some code here */
try
{
/* some specific code that I know may throw, and want to log about */
}
catch( ... )
{
log( "an exception occurred when doing something with some other data" );
throw;
}
/* some code here */
}
简而言之,如果发生异常,创建一个 catch-all 子句,记录错误,然后重新抛出。在我看来,这是安全的。我知道一般来说,包罗万象被认为是不好的,因为根本没有对异常的引用来获取任何有用的信息。但是,我只是要重新抛出它,所以不会丢失任何东西。
现在,它自己没问题,但其他一些程序员修改了这个程序,最终违反了上述规定。具体来说,他们在一种情况下将大量代码放入 try block 中,而在另一种情况下删除了“throw”并放置了“return”。
现在我发现我的解决方案很脆弱;它不是 future 修改的证明。
我想要一个没有这些问题的更好的解决方案。
我有另一个没有上述问题的潜在解决方案,但我想知道其他人对此有何看法。它使用 RAII,特别是一个“Scoped Exit”对象,如果 std::uncaught_exception
在构建时不为真,但在为时隐式触发销毁:
#include <ciso646> // not, and
#include <exception> // uncaught_exception
class ExceptionTriggeredLog
{
private:
std::string const m_log_message;
bool const m_was_uncaught_exception;
public:
ExceptionTriggeredLog( std::string const& r_log_message )
: m_log_message( r_log_message ),
m_was_uncaught_exception( std::uncaught_exception() )
{
}
~ExceptionTriggeredLog()
{
if( not m_was_uncaught_exception
and std::uncaught_exception() )
{
try
{
log( m_log_message );
}
catch( ... )
{
// no exceptions can leave an destructor.
// especially when std::uncaught_exception is true.
}
}
}
};
void potential_function()
{
/* some code here */
{
ExceptionTriggeredLog exception_triggered_log( "an exception occurred when doing something with some other data" );
/* some specific code that I know may throw, and want to log about */
}
/* some code here */
}
我想知道:
std::uncaught_exception
有一些注意事项。注意:我已经更新了这个问题。具体来说,我已经:
log
函数调用周围添加了最初缺失的 try
/catch
。std::uncaught_exception
状态。这可以防止在另一个析构函数的“try” block 内创建此对象的情况,该析构函数作为异常堆栈展开的一部分被触发。最佳答案
我对你的方法没有意见,但看起来很有趣!我有另一种方法也可以满足您的需求,并且可能更通用一些。不过,它需要来自 C++11 的 lambda,这在您的情况下可能是也可能不是问题。
这是一个简单的函数模板,它接受 lambda、运行它并捕获、记录并重新抛出所有异常:
template <typename F>
void try_and_log (char const * log_message, F code_block)
{
try {
code_block ();
} catch (...) {
log (log_message);
throw;
}
}
你使用它的方式(在最简单的情况下)是这样的:
try_and_log ("An exception was thrown here...", [&] {
this_is_the_code ();
you_want_executed ();
and_its_exceptions_logged ();
});
正如我之前所说,我不知道它与您自己的解决方案相比如何。请注意,lambda 正在捕获其封闭范围内的一切,这非常方便。另请注意,我还没有实际尝试过,因此可能会导致编译错误、逻辑问题和/或核 war 。
我在这里看到的问题是,将其包装到宏中并不容易,并希望您的同事正确编写 [=] {
和 }
部分而且所有的时间可能太多了!
出于包装和防白痴的目的,您可能需要两个宏:一个 TRY_AND_LOG_BEGIN
发出第一行直到 lambda 的左大括号和一个 TRY_AND_LOG_END
发出右大括号和括号。像这样:
#define TRY_AND_LOG_BEGIN(message) try_and_log (message, [&] {
#define TRY_AND_LOG_END() })
然后你像这样使用它们:
TRY_AND_LOG_BEGIN ("Exception happened!") // No semicolons here!
whatever_code_you_want ();
TRY_AND_LOG_END ();
这是 - 取决于您的观点 - 是净 yield 还是净损失! (我个人更喜欢直接的函数调用和 lambda 语法,这给了我更多的控制权和透明度。
另外,也可以在代码块的末尾写入日志信息;只需切换 try_and_log
函数的两个参数即可。
关于c++ - 触发异常时应该如何记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15504166/
我正在尝试在Elasticsearch中返回的值中考虑地理位置的接近性。我希望近距离比某些字段(例如legal_name)重要,但比其他字段重要。 从文档看来,当前的方法是使用distance_fea
我是Elasticsearch的初学者,今天在进行“多与或”查询时遇到问题。 我有一个SQL查询,需要在Elastic中进行转换: WHERE host_id = 999 AND psh_pid =
智能指针应该/可以在函数中通过引用传递吗? 即: void foo(const std::weak_ptr& x) 最佳答案 当然你可以通过const&传递一个智能指针。 这样做也是有原因的: 如果接
我想执行与以下MYSQL查询等效的查询 SELECT http_user, http_req_method, dst dst_port count(*) as total FROM my_table
我用这两个查询进行测试 用must查询 { "size": 200, "from": 0, "query": { "bool": { "must": [ { "mat
我仍在研究 Pro Android 2 的简短服务示例(第 304 页)同样,服务示例由两个类组成:如下所示的 BackgroundService.java 和如下所示的 MainActivity.j
给定标记 like this : header really_wide_table..........................................
根据 shouldJS 上的文档网站我应该能够做到这一点: ''.should.be.empty(); ChaiJS网站没有使用 should 语法的示例,但它列出了 expect 并且上面的示例似乎
我在 Stack Overflow 上读到一些 C 函数是“过时的”或“应该避免”。你能给我一些这种功能的例子以及原因吗? 这些功能有哪些替代方案? 我们可以安全地使用它们 - 有什么好的做法吗? 最
在 C++11 中,可变参数模板允许使用任意数量的参数和省略号运算符 ... 调用函数。允许该可变参数函数对每个参数做一些事情,即使每个参数的事情不是一样的: template void dummy(
我在我从事的项目之一上将Shoulda与Test::Unit结合使用。我遇到的问题是我最近更改了此设置: class MyModel :update end 以前,我的(通过)测试看起来像这样: c
我该如何做 or使用 chai.should 进行测试? 例如就像是 total.should.equal(4).or.equal(5) 或者 total.should.equal.any(4,5)
如果您要将存储库 B 中的更改 merge 到存储库 A 中,是否应该 merge .hgtags 中的更改? 存储库 B 可能具有 A 中没有的标签 1.01、1.02、1.03。为什么要将这些 m
我正在尝试执行X AND(y OR z)的查询 我需要获得该代理为上市代理或卖方的所有已售属性(property)。 我只用 bool(boolean) 值就可以得到9324个结果。当我添加 bool
我要离开 this教程,尝试使用 Mocha、Supertest 和 Should.js 进行测试。 我有以下基本测试来通过 PUT 创建用户接受 header 中数据的端点。 describe('U
我正在尝试为 Web 应用程序编写一些 UI 测试,但有一些复杂的问题希望您能帮助我解决。 首先,该应用程序有两种模式。其中一种模式是“训练”,另一种是“现场”。在实时模式下,数据直接从我们的数据库中
我有一个规范: require 'spec_helper' # hmm... I need to include it here because if I include it inside desc
我正在尝试用这个测试我在 Rails 中的更新操作: context "on PUT to :update" do setup do @countdown = Factory(:count
我还没有找到合适的答案: onclick="..." 中是否应该转义 &(& 符号)? (或者就此而言,在每个 HTML 属性中?) 我已经尝试在 jsFiddle 和 W3C 的验证器上运行转义和非
import java.applet.*; import java.awt.*; import java.awt.event.*; public class Main extends Applet i
我是一名优秀的程序员,十分优秀!