config/Data: add WithEach(ConfigBlockOption)

To improve error messages without making callers more complex.
This commit is contained in:
Max Kellermann
2022-07-12 21:02:49 +02:00
parent 89a18b49a7
commit ae4f4d3533
5 changed files with 46 additions and 20 deletions

View File

@@ -143,3 +143,10 @@ ConfigBlock::GetBlockValue(const char *name, bool default_value) const
return bp->GetBoolValue();
}
void
ConfigBlock::ThrowWithNested() const
{
std::throw_with_nested(FormatRuntimeError("Error in block on line %i",
line));
}

View File

@@ -137,6 +137,14 @@ struct ConfigBlock {
unsigned GetPositiveValue(const char *name, unsigned default_value) const;
bool GetBlockValue(const char *name, bool default_value) const;
/**
* Call this method in a "catch" block to throw a nested
* exception showing the location of this block in the
* configuration file.
*/
[[noreturn]]
void ThrowWithNested() const;
};
#endif

View File

@@ -121,6 +121,26 @@ struct ConfigData {
ConfigBlock &MakeBlock(ConfigBlockOption option,
const char *key, const char *value);
/**
* Invoke the given function for each instance of the
* specified block.
*
* Exceptions thrown by the function will be nested in one
* that specifies the location of the block.
*/
template<typename F>
void WithEach(ConfigBlockOption option, F &&f) const {
for (const auto &block : GetBlockList(option)) {
block.SetUsed();
try {
f(block);
} catch (...) {
block.ThrowWithNested();
}
}
}
};
#endif