如何使用Apache Thrift在单个catch语句中捕获所有自定义异常?

时间:2015-11-20 11:20:48

标签: c++ rpc thrift c++03

我在exception InvalidArgumentsError { 1: string parameter } /** * Server has an problem while executing a function. * Execution aborted. */ exception ServerInternalError { 1: string parameter } /** * Server answer is empty. */ exception NoDataError { 1: string parameter } 中定义了许多不同的例外:

catch (InvalidArgumentsError & ex) {
  std::cout << ex.parameter;
}
catch (ServerInternalError & ex) {
  std::cout << ex.parameter;
}
catch (NoDataError & ex) {
  std::cout << ex.parameter;
}
catch (apache::thrift::TException& ex) {
  std::cout << "TException:\n" << ex.what();
} catch (const std::exception& ex) {
  std::cout << ex.what();
   return;
}

这就是我在C ++代码中捕获它们的方式:

catch (SomeBasicException& ex) {
  std::cout << ex.what();
} 
catch (const std::exception& ex) {
  std::cout << ex.what();
}

我想写这样的东西并抓住我所有的例外:

TException

如果我只是抓住what()并调用what(),我只会收到'Default TException'消息,因为派生类不会覆盖虚拟class InvalidArgumentsError : public ::apache::thrift::TException { public: static const char* ascii_fingerprint; //.. static const uint8_t binary_fingerprint[16]; //.. InvalidArgumentsError() : parameter() { } virtual ~InvalidArgumentsError() throw() {} std::string parameter; _InvalidArgumentsError__isset __isset; void __set_parameter(const std::string& val) { parameter = val; } //... }; 方法。

由thrift编译器生成的代码:

app.get('/node/parislight/myapp/demo', function (req, res) {
  res.send('Hello World!')
})

2 个答案:

答案 0 :(得分:2)

如果您想停止重复输入,那么这可能是一个解决方案。

如果你想捕捉异常,你可以这样写:

catch (...) {
    handle_exception(print_message);
}

print_message是一个函数,它可以对消息执行任何操作(在本例中为打印):

void print_message(char const* const msg)
{
    std::cout << msg;
}

handle_exception写得像这样:

template<typename F>
void handle_exception(F handler)
try {
    throw;
}
catch (InvalidArgumentsError const& ex) {
    handler(ex.parameter.c_str());
}
catch (ServerInternalError const& ex) {
    handler(ex.parameter.c_str());
}
catch (NoDataError const& ex) {
    handler(ex.parameter.c_str());
}
catch (apache::thrift::TException const& ex) {
    handler(ex.what());
}
catch (std::exception const& ex) {
    handler(ex.what());
}

要处理新的异常,请将其添加到catch函数的handle_exception子句中。

答案 1 :(得分:1)

虽然这并没有真正回答这个问题(@Simple已经很好地解决了这个问题)我想提出一个不同的方法。

鉴于上面发布的代码:

exception InvalidArgumentsError {
    1: string parameter
}

exception ServerInternalError {
    1: string parameter
}

exception NoDataError {
    1: string parameter
}

如果我们看一下模式,我们可以 - 在不丢失任何信息且不产生更多不兼容性的情况下 - 将其更改为:

enum ErrorCode
  Success = 0, // always good to have some null value
  ServerInternalError = 1
  NoData = 2
  InvalidArguments = 3
  // add more errors here
}

exception MyServiceException {
    1: string parameter
    2: ErrorCode  code
}

我完全清楚这可能不适合您的特定问题(例如,如果有更多的异常数据而不仅仅是1:parameter)。但可能有些情况下这种方法值得考虑。我已经使用过很多次了。