是否有事实上的标准例外或最佳实践方法来发出异常"invalid input"信号?

Is there a defacto standard exception or best-practice way in signalling "invalid input" by exception?

本文关键字:异常 invalid 信号 input 方法 标准 事实上 最佳 是否      更新时间:2023-10-16

invalid_argument is-a - logic_error

两个参考点都表示

行上的内容

这个类[i.e. logic_error]定义了作为异常抛出的对象类型,用于报告程序内部逻辑中的错误,例如违反逻辑前提条件或类不变量。

这些错误可以在程序执行之前检测到。

问题:接受invalid_argument的语义严格约束于"程序员的错误",是否有任何事实上的标准异常程序/库/服务器可以使用++运行时与外部调用方通信"提供的输入无效"?
您以前的经验是否显示了使用"invalid_input"类型异常的常规模式?
如果是这样,它是标准的还是每个人都只是根据需要派生他们的异常?

指出:

  1. 显然,stdexcept没有提供runtime语义。boost

  2. 虽然我知道/遵循尽可能早的验证规则,但我发现经常有输入数据(无论是否来自用户)只能在更深的上下文中进行验证的情况:尽可能早的可能需要与更深的上下文中进行匹配,而"在网关"不可用。


++ "to communication " =在调用链中(或者在堆栈跟踪中,如果你喜欢的话)有一个像

这样的块
// fwd declaration
void function_facing_dirty_code(struct user_input& data);
void function_facing_the_user(const char* jsonArgs) {
  try {
    struct user_input;
    parse_user_input(json_args, user_input);
    function_facing_dirty_code(user_input);
  }
  catch(invalid_input& ii) {
    // **this** should be a standard error for erroneous input/args/etc
    // treat it by telling the out-of-my-control caller to behave
  }
  catch (std::runtime_exception& e) {
    // tell the caller: sorry, you've done nothing wrong,
    // but I'm having generic runtime troubles.
  }
}
void function_facing_dirty_code(struct user_input& data) {
  try {
    // ... do some work
    // ... do some more work
    // Ahhh
    throw std::invalid_argument("Requested amount over the daily redraw limit");
    // ooops. This will cause a BSoD instead of telling the user.
    // Because std::invalid_argument is a logic error
  }
  catch(std::logic_error& bsod) {
    // log an error, blame the author, snitch it to his boss,
    // then generate a BSoD for the user's delight,
    // because she must NOT see our coding family's dirty laundry
  }
}

std::logic_error和派生类背后的想法有点像一个美化的断言——在标准库中,它们的使用方式有点像(想想vector::at——你想从无效的向量索引中获得什么样的恢复?这只是意味着逻辑是拙劣的,它只是一个友好的替代UB);invalid_argument也用于类似的事情,IIRC在std::bitset

但是我同意,一般来说,"无效参数"类型的异常可以派生自"逻辑"或"运行时"错误;我在这里的主要观点是:不要在没有逻辑的地方寻求太多逻辑。

整个<stdexcept>的事情看起来像是在晚餐前草草记下来的,然后完全忘记了。非常广泛的错误类别被直接划分为逻辑/运行时二分法(有争议的价值),本质上是基于它们如何在标准库中被使用;那些没有被使用的(这应该是一个方便的程序员)是随机的选择(overflow/underflow/domain_error -也许他们只是在考虑数学函数?)和表征(out_of_range是"逻辑",但overflow是"运行时"?

简而言之:不要过度思考stdexcept的想法-它们是模糊的,有争议的,然后被锤打以适应标准库的一些需求。从std::exceptionstd::runtime_error派生出对您的应用程序有意义的异常层次结构,并满意地使用它。