1
1
forked from 0ad/0ad
0ad/source/lib/lib_errors.h
janwas e0280949fd file_cache: fix: add buf/size combo to exact_buf_oracle if file_io rounded size up.
trace: split code out of vfs_optimizer (was getting too large)
vfs_mount: expose API to unmount all (needed to be able to delete
archives after building)
vfs_optimizer: safely handle empty connection/node lists;
refactored+documented
vfs_tree: eliminate 'file in root dir' warning (can happen easily
enough)

rest: fixes/minor tweaks

This was SVN commit r3610.
2006-03-07 05:44:34 +00:00

342 lines
12 KiB
C

// notes:
// - file is called lib_errors.h because 0ad has another errors.cpp and
// the MS linker isn't smart enough to deal with object files
// of the same name but in different paths.
// - the first part of this file is a normal header; the second contains
// X macros and is only active if ERR is defined (i.e. someone is
// including this header for the purpose of using them).
#ifndef ERRORS_H__
#define ERRORS_H__
// limits on the errors defined above (used by error_description_r)
#define ERR_MIN 100000
#define ERR_MAX 110000
// define error codes.
enum LibError {
#define ERR(err, id, str) id = err,
#include "lib_errors.h"
// necessary because the enum would otherwise end with a comma
// (which is often tolerated but not standards compliant).
// note: we cannot rely on this being the last value (in case the
// ERR x-macros aren't arranged in order), so don't use as such.
LIB_ERROR_DUMMY
};
// choices offered by the shared error dialog
enum ErrorReaction
{
// ignore, continue as if nothing happened.
// note: don't start at 0 because that is interpreted as a
// DialogBoxParam failure.
ER_CONTINUE = 1,
// ignore and do not report again.
// only returned if DE_ALLOW_SUPPRESS was passed.
// note: non-persistent; only applicable during this program run.
ER_SUPPRESS,
// trigger breakpoint, i.e. enter debugger.
// only returned if DE_MANUAL_BREAK was passed; otherwise,
// debug_display_error will trigger a breakpoint itself.
ER_BREAK,
// exit the program immediately.
// never returned; debug_display_error exits immediately.
ER_EXIT
};
// generate textual description of an error code.
// stores up to <max_chars> in the given buffer.
// if error is unknown/invalid, the string will be something like
// "Unknown error (65536, 0x10000)".
extern void error_description_r(LibError err, char* buf, size_t max_chars);
// return the LibError equivalent of errno, or ERR_FAIL if there's no equal.
// only call after a POSIX function indicates failure.
extern LibError LibError_from_errno();
// translate the return value of any POSIX function into LibError.
// ret is typically to -1 to indicate error and 0 on success.
// you should set errno to 0 before calling the POSIX function to
// make sure we do not return any stale errors.
extern LibError LibError_from_posix(int ret);
// set errno to the equivalent of <err>. used in wposix - underlying
// functions return LibError but must be translated to errno at
// e.g. the mmap interface level. higher-level code that calls mmap will
// in turn convert back to LibError.
extern void LibError_set_errno(LibError err);
// be careful here. the given expression (e.g. variable or
// function return value) may be a Handle (=i64), so it needs to be
// stored and compared as such. (very large but legitimate Handle values
// casted to int can end up negative)
// all functions using this return LibError (instead of i64) for
// efficiency and simplicity. if the input was negative, it is an
// error code and is therefore known to fit; we still mask with
// UINT_MAX to avoid VC cast-to-smaller-type warnings.
// if expression evaluates to a negative i64, warn user and return the number.
#if OS_WIN
#define CHECK_ERR(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return err;\
}\
)
#else
#define CHECK_ERR(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return (LibError)(err & UINT_MAX);\
}\
)
#endif
// just pass on errors without any kind of annoying warning
// (useful for functions that can legitimately fail, e.g. vfs_exists).
#define RETURN_ERR(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
return err;\
}\
)
// return an error and warn about it (replaces debug_warn+return)
#define WARN_RETURN(err)\
STMT(\
DEBUG_WARN_ERR(err);\
return err;\
)
// if expression evaluates to a negative i64, warn user and throw the number.
#define THROW_ERR(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
throw err;\
}\
)
// if expression evaluates to a negative i64, warn user and just return
// (useful for void functions that must bail and complain)
#define WARN_ERR_RETURN(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
return;\
}\
)
// if expression evaluates to a negative i64, warn user
// (this is similar to debug_assert but also works in release mode)
#define WARN_ERR(expression)\
STMT(\
i64 err64 = (i64)(expression);\
if(err64 < 0)\
{\
LibError err = (LibError)(err64 & UINT_MAX);\
DEBUG_WARN_ERR(err);\
}\
)
// if ok evaluates to false or FALSE, warn user and return -1.
#define WARN_RETURN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
{\
debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\
"feel free to ignore or suppress this warning.");\
return ERR_FAIL;\
}\
)
// if ok evaluates to false or FALSE, return -1.
#define RETURN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
return ERR_FAIL;\
)
// if ok evaluates to false or FALSE, warn user.
#define WARN_IF_FALSE(ok)\
STMT(\
if(!(ok))\
debug_warn("FYI: WARN_IF_FALSE reports that a function failed."\
"feel free to ignore or suppress this warning.");\
)
#endif // #ifndef ERRORS_H__
//-----------------------------------------------------------------------------
#ifdef ERR
// X macros: error code, symbolic name in code, user-visible string.
// error code is usually negative; positive denotes warnings.
// its absolute value must be within [ERR_MIN, ERR_MAX).
// ERR_OK doesn't really need a string, but must be part of enum LibError
// due to compiler checks. (and calling error_description_r(0) should
// never happen, but we set the text accordingly..)
ERR(0, ERR_OK, "(but return value was 0 which indicates success)")
ERR(-1, ERR_FAIL, "Function failed (no details available)")
// note: these values are > 100 to allow multiplexing them with
// coroutine return values, which return completion percentage.
ERR(101, INFO_CB_CONTINUE, "1 (not an error)")
// these are all basically the same thing
ERR(102, INFO_CANNOT_HANDLE, "2 (not an error)")
ERR(103, INFO_NO_REPLACE, "3 (not an error)")
ERR(104, INFO_SKIPPED, "4 (not an error)")
ERR(105, INFO_ALL_COMPLETE, "5 (not an error)")
ERR(106, INFO_ALREADY_PRESENT, "6 (not an error)")
ERR(-100000, ERR_LOGIC, "Logic error in code")
ERR(-100060, ERR_TIMED_OUT, "Timed out")
// these are for cases where we just want a distinct value to display and
// a symbolic name + string would be overkill (e.g. the various
// test cases in a validate() call). they are shared between multiple
// functions; when something fails, the stack trace will show in which
// one it was => these errors are unambiguous.
// there are 3 tiers - 1..9 are used in most functions, 11..19 are
// used in a function that calls another validator and 21..29 are
// for for functions that call 2 other validators (this avoids
// ambiguity as to which error actually happened where)
ERR(-100101, ERR_1, "Case 1")
ERR(-100102, ERR_2, "Case 2")
ERR(-100103, ERR_3, "Case 3")
ERR(-100104, ERR_4, "Case 4")
ERR(-100105, ERR_5, "Case 5")
ERR(-100106, ERR_6, "Case 6")
ERR(-100107, ERR_7, "Case 7")
ERR(-100108, ERR_8, "Case 8")
ERR(-100109, ERR_9, "Case 9")
ERR(-100111, ERR_11, "Case 11")
ERR(-100112, ERR_12, "Case 12")
ERR(-100113, ERR_13, "Case 13")
ERR(-100114, ERR_14, "Case 14")
ERR(-100115, ERR_15, "Case 15")
ERR(-100116, ERR_16, "Case 16")
ERR(-100117, ERR_17, "Case 17")
ERR(-100118, ERR_18, "Case 18")
ERR(-100119, ERR_19, "Case 19")
ERR(-100121, ERR_21, "Case 21")
ERR(-100122, ERR_22, "Case 22")
ERR(-100123, ERR_23, "Case 23")
ERR(-100124, ERR_24, "Case 24")
ERR(-100125, ERR_25, "Case 25")
ERR(-100126, ERR_26, "Case 26")
ERR(-100127, ERR_27, "Case 27")
ERR(-100128, ERR_28, "Case 28")
ERR(-100129, ERR_29, "Case 29")
// function arguments
ERR(-100220, ERR_INVALID_PARAM, "Invalid function argument")
ERR(-100221, ERR_INVALID_HANDLE, "Invalid Handle (argument)")
ERR(-100222, ERR_BUF_SIZE, "Buffer argument too small")
// system limitations
ERR(-100240, ERR_NO_MEM, "Not enough memory")
ERR(-100241, ERR_AGAIN, "Try again later")
ERR(-100242, ERR_LIMIT, "Fixed limit exceeded")
ERR(-100243, ERR_NO_SYS, "OS doesn't provide a required API")
ERR(-100244, ERR_NOT_IMPLEMENTED, "Feature currently not implemented")
ERR(-100245, ERR_NOT_SUPPORTED, "Feature isn't and won't be supported")
// file + vfs
ERR(-100300, ERR_FILE_NOT_FOUND, "VFile not found")
ERR(-100301, ERR_PATH_NOT_FOUND, "VDir not found")
ERR(-100302, ERR_PATH_LENGTH, "Path exceeds VFS_MAX_PATH characters")
ERR(-100303, ERR_PATH_INVALID, "Path is invalid")
ERR(-100310, ERR_DIR_END, "End of directory reached (no more files)")
ERR(-100320, ERR_NOT_FILE, "Not a file")
ERR(-100321, ERR_NOT_DIR, "Not a directory")
ERR(-100330, ERR_FILE_ACCESS, "Insufficient access rights to open file")
ERR(-100331, ERR_IO, "Error during IO")
ERR(-100332, ERR_EOF, "Reading beyond end of file")
ERR(-100340, ERR_UNKNOWN_CMETHOD, "Unknown/unsupported compression method")
ERR(-100341, ERR_IS_COMPRESSED, "Invalid operation for a compressed file")
ERR(-100350, ERR_ALREADY_MOUNTED, "Directory (tree) already mounted")
ERR(-100351, ERR_INVALID_MOUNT_TYPE, "Invalid mount type (memory corruption?)")
ERR(-100360, ERR_NOT_IN_CACHE, "[Internal] Entry not found in cache")
ERR(-100370, ERR_TRACE_EMPTY, "No valid entries in trace")
// file format
ERR(-100400, ERR_UNKNOWN_FORMAT, "Unknown file format")
ERR(-100401, ERR_INCOMPLETE_HEADER, "File header not completely read")
ERR(-100402, ERR_CORRUPTED, "File data is corrupted")
// texture
ERR(-100500, ERR_TEX_FMT_INVALID, "Invalid/unsupported texture format")
ERR(-100501, ERR_TEX_INVALID_COLOR_TYPE, "Invalid color type")
ERR(-100502, ERR_TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision")
ERR(-100503, ERR_TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left")
ERR(-100504, ERR_TEX_COMPRESSED, "Unsupported texture compression")
ERR(+100505, WARN_TEX_INVALID_DATA, "Warning: invalid texel data encountered")
ERR(-100506, ERR_TEX_INVALID_SIZE, "Texture size is incorrect")
ERR(-100507, ERR_TEX_CODEC_CANNOT_HANDLE, "Texture codec cannot handle the given format")
// CPU
ERR(-100600, ERR_CPU_FEATURE_MISSING, "This CPU doesn't support a required feature")
// shaders
ERR(-100700, ERR_SHDR_CREATE, "Shader creation failed")
ERR(-100701, ERR_SHDR_COMPILE, "Shader compile failed")
ERR(-100702, ERR_SHDR_NO_SHADER, "Invalid shader reference")
ERR(-100703, ERR_SHDR_LINK, "Shader linking failed")
ERR(-100704, ERR_SHDR_NO_PROGRAM, "Invalid shader program reference")
// debug symbol engine
ERR(-100800, ERR_SYM_NO_STACK_FRAMES_FOUND, "No stack frames found")
ERR(-100801, ERR_SYM_UNRETRIEVABLE_STATIC, "Value unretrievable (stored in external module)")
ERR(-100802, ERR_SYM_UNRETRIEVABLE_REG, "Value unretrievable (stored in register)")
ERR(-100803, ERR_SYM_TYPE_INFO_UNAVAILABLE, "Error getting type_info")
// .. this limit is to prevent infinite recursion.
ERR(-100804, ERR_SYM_NESTING_LIMIT, "Symbol nesting too deep or infinite recursion")
// .. this limit is to prevent large symbols (e.g. arrays or linked lists) from
// hogging all stack trace buffer space.
ERR(-100805, ERR_SYM_SINGLE_SYMBOL_LIMIT, "Symbol has produced too much output")
ERR(-100806, ERR_SYM_INTERNAL_ERROR, "Exception raised while processing a symbol")
ERR(-100807, ERR_SYM_UNSUPPORTED, "Symbol type not (fully) supported")
// .. one of the dump_sym* functions decided not to output anything at
// all (e.g. for member functions in UDTs - we don't want those).
// therefore, skip any post-symbol formatting (e.g. ",") as well.
ERR(-100808, ERR_SYM_SUPPRESS_OUTPUT, "Symbol was suppressed")
ERR(-100809, ERR_SYM_CHILD_NOT_FOUND, "Symbol does not have the given child")
// STL debug
ERR(-100900, ERR_STL_CNT_UNKNOWN, "Unknown STL container type_name")
// .. likely causes: not yet initialized or memory corruption.
ERR(-100901, ERR_STL_CNT_INVALID, "Container type is known but contents are invalid")
#undef ERR
#endif // #ifdef ERR