Files
bluelib/test/term/errors.c

139 lines
3.3 KiB
C
Raw Normal View History

#include <blue/core/error.h>
#include <blue/term/print.h>
#include <stdio.h>
enum sample_code {
SAMPLE_OK = 0,
SAMPLE_ERR_IO_FAILURE,
SAMPLE_ERR_FILE_READ_FAILED,
};
enum sample_msg {
SAMPLE_MSG_SUCCESS = 0,
SAMPLE_MSG_A_TEMPLATED_MSG,
};
static const b_error_definition sample_errors[] = {
B_ERROR_DEFINITION(SAMPLE_OK, "OK", "Success"),
B_ERROR_DEFINITION(SAMPLE_ERR_IO_FAILURE, "IO_FAILURE", "I/O failure"),
B_ERROR_DEFINITION_TEMPLATE(
SAMPLE_ERR_FILE_READ_FAILED, "FILE_READ_FAILED",
"Failed to read file @i[filepath]",
B_ERROR_TEMPLATE_PARAM(
"filepath", B_ERROR_TEMPLATE_PARAM_STRING, "%s")),
};
static const b_error_msg sample_error_msg[] = {
B_ERROR_MSG_TEMPLATE(
SAMPLE_MSG_A_TEMPLATED_MSG, "A templated message: @e[param1]",
B_ERROR_TEMPLATE_PARAM(
"param1", B_ERROR_TEMPLATE_PARAM_STRING, "%s")),
};
static const char *sample_code_to_string(
const struct b_error_vendor *vendor, b_error_status_code code)
{
switch (code) {
case SAMPLE_OK:
return "OK";
case SAMPLE_ERR_IO_FAILURE:
return "IO_FAILURE";
case SAMPLE_ERR_FILE_READ_FAILED:
return "FILE_READ_FAILED";
default:
return NULL;
}
}
static b_error_vendor sample_vendor = {
.v_name = "Sample",
.v_error_definitions = sample_errors,
.v_error_definitions_length = sizeof sample_errors,
.v_msg = sample_error_msg,
.v_msg_length = sizeof sample_error_msg,
};
static b_result error_return_3(void)
{
b_result err = b_error_with_string(
&sample_vendor, SAMPLE_ERR_IO_FAILURE,
"I/O failure while reading file");
b_error_add_submsg_string(
err, B_ERROR_SUBMSG_ERROR, "An @e{error} message");
b_error_add_submsg_string(
err, B_ERROR_SUBMSG_WARNING, "A @w{warning} message");
b_error_add_submsg_template(
err, B_ERROR_SUBMSG_WARNING, SAMPLE_MSG_A_TEMPLATED_MSG,
B_ERROR_PARAM("param1", "Hello!"));
return err;
}
static b_result error_return_2(void)
{
return b_result_propagate(error_return_3());
}
static b_result error_return_1(void)
{
return b_result_propagate(error_return_2());
}
struct param {
const char *name;
int value;
};
#define PARAM(n, v) \
(struct param) \
{ \
.name = (n), .value = (v) \
}
static void __test(struct param params[])
{
for (size_t i = 0; params[i].name; i++) {
printf("%s = %d\n", params[i].name, params[i].value);
}
}
#define test(...) __test((struct param[]) {__VA_ARGS__, {}})
static b_result some_operation(void)
{
b_result result = error_return_2();
if (b_result_is_error(result)) {
b_result err = b_error_with_template(
&sample_vendor, SAMPLE_ERR_FILE_READ_FAILED,
B_ERROR_PARAM("filepath", "src/Manifest.json"));
b_error_add_submsg_string(
err, B_ERROR_SUBMSG_INFO,
"An @i{informational} message");
b_error_caused_by_b_status(result, B_ERR_IO_FAILURE);
b_result err2 = b_error_caused_by(err, result);
return err2;
}
return B_RESULT_SUCCESS;
}
int main(void)
{
b_set_error_report_function(b_enhanced_error_reporter, B_ERROR_REPORT_ALL);
test(PARAM("Hello", 1), PARAM("Goodbye", 2));
b_result err;
if (B_CATCH(err, some_operation())) {
b_throw(err);
}
b_throw_status(B_ERR_INVALID_ARGUMENT);
b_throw_status_string(B_ERR_INVALID_ARGUMENT, "Hello!");
return 0;
}