1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
/**
* @file
* @brief Handling of error conditions that are not program bugs.
**/
#include "AppHdr.h"
#include "errors.h"
#include <cerrno>
#include <cstdarg>
#include <cstring>
#include "stringutil.h"
#include "syscalls.h"
NORETURN void fail(const char *msg, ...)
{
va_list args;
va_start(args, msg);
string buf = vmake_stringf(msg, args);
va_end(args);
// Do we want to call end() right on when there's no one trying catching,
// or should we risk exception code mess things up?
throw ext_fail_exception(buf);
}
NORETURN void sysfail(const char *msg, ...)
{
va_list args;
va_start(args, msg);
string buf = vmake_stringf(msg, args);
va_end(args);
buf += ": ";
buf += strerror(errno);
throw ext_fail_exception(buf);
}
NORETURN void corrupted(const char *msg, ...)
{
va_list args;
va_start(args, msg);
string buf = vmake_stringf(msg, args);
va_end(args);
throw corrupted_save(buf);
}
/**
* Toss failures from a test into stderr & an error file, if there were any
* failures.
*
* @param fails The failures, if any.
* @param name Errors are dumped to "[name].out"; name should be unique.
*/
void dump_test_fails(string fails, string name)
{
if (fails.empty())
return;
fprintf(stderr, "%s", fails.c_str());
const string outfile = make_stringf("%s.out", name.c_str());
FILE *f = fopen_u(outfile.c_str(), "w");
if (!f)
sysfail("can't write test output");
fprintf(f, "%s", fails.c_str());
fclose(f);
fail("%s event errors (dumped to %s)",
name.c_str(), outfile.c_str());
}
|