#pragma once /// \file global.h /// \author Folling #include /// \addtogroup errors Errors /// \brief Error handling within libikarus /// \details Functions in Ikarus may fail, in which case they have an out parameter for the error. /// Upon erring the function will store relevant information about the error in the out parameter. /// If the out parameter is null nothing will be stored. This is not recommended as it essentially ignores errors. /// For the sake of simplicity we have avoided mechanisms that "force" clients to handle errors. /// Note that Ikarus does not check for null pointers. Passing null pointers to functions that do not explicitly state that they accept null /// pointers is undefined behaviour. This decision is done for the sake of brevity and readability. `project_get_name(project)` is also /// synonymous to `project->get_name()` in OOP languages, which shares the same semantics. /// @{ IKARUS_BEGIN_HEADER /// \brief Delineates what caused an error. /// \remark Note that this doesn't show responsibility. An error with source "SubSystem" could still be the /// fault of libikarus, it just indicates where the error occurred. enum IkarusErrorInfo { /// \brief No error occurred. IkarusErrorInfo_None = 0x0, /// \brief The error was caused by the client. IkarusErrorInfo_Client = 0x10100000, /// \brief The error was caused by a dependency (e.g. boost) of libikarus. IkarusErrorInfo_Dependency = 0x10200000, /// \brief The error was caused by the filesystem. IkarusErrorInfo_Filesystem = 0x10300000, /// \brief The error was caused by the database. IkarusErrorInfo_Database = 0x10400000, /// \brief The error was caused by the underlying OS. IkarusErrorInfo_OS = 0x10500000, /// \brief The error was caused by libikarus itself. IkarusErrorInfo_LibIkarus = 0x10600000, /// \brief The client misused the API. /// Example: Accessing a resource that does not exist. IkarusErrorInfo_Client_Misuse = 0x10100001, /// \brief The client provided a null value for a parameter that must not be null. /// Example: Passing null for `ikarus_project_get_name` IkarusErrorInfo_Client_InvalidNull = 0x10100002, /// \brief The client provided an index that was out of bounds for some array. /// Example: Passing the index 3 for an `IkarusToggleValue` with size 3. IkarusErrorInfo_Client_IndexOutOfBounds = 0x10100003, /// \brief The client provided a numeric value that was out of bounds /// Example: Passing the value 2^32 to an i32 (might be passed as a string). IkarusErrorInfo_Client_ValueOutOfBounds = 0x10100004, /// \brief The client provided invalid input that doesn't fit in any of the other categories. /// Example: Passing an empty/blank string for a string that must be non-empty/-blank. IkarusErrorInfo_Client_InvalidInput = 0x10100005, /// \brief The client provided valid data in an invalid format. /// Example: Passing a malformed JSON string. IkarusErrorInfo_Client_InvalidFormat = 0x10100006, /// \brief The client violated a constraint. /// \details This error is most likely caused by endusers. /// Example: A user tries to set the age of a character to an value outside of their specified range. IkarusErrorInfo_Client_ConstraintViolated = 0x10100007, /// \brief A file was not found. IkarusErrorInfo_Filesystem_NotFound = 0x10300001, /// \brief A file or directory already exists. IkarusErrorInfo_Filesystem_AlreadyExists = 0x10300002, /// \brief Missing permissions to access a file or directory. IkarusErrorInfo_Filesystem_MissingPermissions = 0x10300003, /// \brief Insufficient space to perform an operation. IkarusErrorInfo_Filesystem_InsufficientSpace = 0x10300004, /// \brief A path is invalid. IkarusErrorInfo_Filesystem_InvalidPath = 0x10300005, /// \brief A database connection failed. IkarusErrorInfo_Database_ConnectionFailed = 0x10400001, /// \brief A database query failed. IkarusErrorInfo_Database_QueryFailed = 0x10400002, /// \brief A database migration failed. IkarusErrorInfo_Database_MigrationFailed = 0x10400003, /// \brief A database is in an invalid state. This indicates a corrupt project. /// Example: An entity is linked to a non-existant blueprint. IkarusErrorInfo_Database_InvalidState = 0x10400004, /// \brief A system call failed. IkarusErrorInfo_OS_SystemCallFailed = 0x10500001, /// \brief A system call returned an invalid value. IkarusErrorInfo_OS_InvalidReturnValue = 0x10500002, /// \brief An OOM error occurred. IkarusErrorInfo_OS_InsufficientMemory = 0x10500003, /// \brief A datapoint within ikarus is invalid for the current state of the system. /// Example: The name of an object is found to be invalid UTF8. IkarusErrorInfo_LibIkarus_InvalidState = 0x20030001, /// \brief libikarus is unable to perform a certain operation within a given timeframe. /// Example: A query takes longer than the timeout. IkarusErrorInfo_LibIkarus_Timeout = 0x20030003, }; /// \brief The data limits for an error. enum IkarusErrorDataLimit { /// \brief The maximum number of error infos that can be stored in an error. IkarusErrorDataLimit_MaxErrorInfos = 8, /// \brief The maximum length of an error message. IkarusErrorDataLimit_MaxMessageLength = 128, }; /// \brief The data stored for an error struct IkarusErrorData { /// \brief The scope of the error. /// \details This array may at most hold #IkarusErrorDataLimit_MaxErrorInfos elements. /// The first occurrence of #IkarusErrorInfo_None signifies the end of the array. If this happens at idx x== 0, no error occurred. IkarusErrorInfo infos[IkarusErrorDataLimit_MaxErrorInfos]; char message[IkarusErrorDataLimit_MaxMessageLength]; }; /// \brief Gets the name of an error info. /// \param info The error info to get the name of. /// \return The name of the error info. /// \remark The returned pointer is valid for the lifetime of the program and must not be freed. IKA_API char const * get_error_info_name(IkarusErrorInfo info); /// \brief Checks if an error data is a success. /// \param data The error data to check. /// \return True if the error data is a success, false otherwise. IKA_API bool ikarus_error_data_is_success(IkarusErrorData const * data); /// \brief Checks if an error data is an error. /// \param data The error data to check. /// \return True if the error data is an error, false otherwise. IKA_API bool ikarus_error_data_is_error(IkarusErrorData const * data); /// \brief Formats the error data in a reasonable but unspecified way. /// \param data The error data to format. /// \return The formatted error data. /// \remark Ownership of the returned pointer is passed to the user and must be freed at their leisure using ikarus_free. IKA_API char const * ikarus_error_data_pretty_format(IkarusErrorData const * data); IKARUS_END_HEADER /// @}