aboutsummaryrefslogtreecommitdiff
path: root/c/err.h
blob: 4c6e82996266fb7f00f6d403640aaf2f48517b5b (plain)
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
#ifndef ERR_H
#define ERR_H

#include <exception>
#include <string>

#include "win32.h"

enum ErrType : unsigned char
{
	GENERIC,
	WINDOWS,
	WININET,
	LIBXML2
};

struct Err
{
	std::wstring what;
	Err(ErrType t, const wchar_t* fmt = L"%s");
	inline Err(ErrType t, std::wstring fmt) : Err(t, fmt.c_str()) {}
};

/* Return a wide string describing exception. */
std::wstring What(std::exception_ptr e = std::current_exception());

/* Exit gracefully on uncaught exception. */
void OnTerminate();

/* Exception-catching version of F that warns on exception. */
template <auto F>
auto Except = (decltype(F))[](auto... xs)
{
	try {
		return F(xs...);
	} catch (...) {
		EBMessageBox(What(), L"Error");
		if constexpr (!std::is_same_v<decltype(F(xs...)), void>)
			return decltype(F(xs...)){};
	}
};

/* Exception-catching version of F that exits on exception. */
template <auto F>
auto Noexcept = (decltype(F))[](auto... xs)
{
	try {
		return F(xs...);
	} catch (...) {
		EBMessageBox(What(), L"Fatal Error", MB_ICONERROR);
		exit(1);
		if constexpr (!std::is_same_v<decltype(F(xs...)), void>)
			return decltype(F(xs...)){};
	}
};

#endif