* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* GR is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* gr_error_handler.h
*
* IDENTIFICATION
* src/common/gr_error_handler.h
*
* -------------------------------------------------------------------------
*/
#ifndef __GR_ERROR_HANDLER_H__
#define __GR_ERROR_HANDLER_H__
#include "cm_error.h"
#include "gr_errno.h"
#include "gr_log.h"
#include "cm_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
* Error category for better error classification
*/
typedef enum {
GR_ERR_CATEGORY_SYSTEM,
GR_ERR_CATEGORY_PARAM,
GR_ERR_CATEGORY_RESOURCE,
GR_ERR_CATEGORY_NETWORK,
GR_ERR_CATEGORY_FILESYSTEM,
GR_ERR_CATEGORY_CONFIG,
GR_ERR_CATEGORY_SESSION,
GR_ERR_CATEGORY_PROTOCOL
} gr_err_category_t;
* Unified error handling macro with category
* Usage: GR_ERROR_HANDLE(GR_ERR_CATEGORY_FILESYSTEM, ERR_GR_FILE_SYSTEM_ERROR, "Failed to open file: %s", path);
*
* IMPORTANT:
* - We MUST use GR_THROW_ERROR_EX here, so that the user-provided format string
* (format) is passed into cm_set_error. If we called GR_THROW_ERROR (which
* uses g_gr_error_desc[code] as the format string), the number and types of
* variadic arguments might not match the default error description, leading
* to undefined behaviour (e.g. vsnprintf reading wrong arguments and causing
* a crash).
*/
#define GR_ERROR_HANDLE(category, code, format, ...) \
do { \
LOG_RUN_ERR("[%s] " format, gr_err_category_name(category), ##__VA_ARGS__); \
GR_THROW_ERROR_EX(code, format, ##__VA_ARGS__); \
} while(0)
* Unified error handling with return
* Usage: GR_ERROR_RETURN(GR_ERR_CATEGORY_FILESYSTEM, ERR_GR_FILE_SYSTEM_ERROR, CM_ERROR, "Failed to open file: %s", path);
*/
#define GR_ERROR_RETURN(category, code, ret_val, format, ...) \
do { \
GR_ERROR_HANDLE(category, code, format, ##__VA_ARGS__); \
return (ret_val); \
} while(0)
* Check condition and return error if false
* Usage: GR_CHECK_RETURN(ptr != NULL, GR_ERR_CATEGORY_PARAM, ERR_GR_INVALID_PARAM, CM_ERROR, "Pointer is NULL");
*/
#define GR_CHECK_RETURN(condition, category, code, ret_val, format, ...) \
do { \
if (SECUREC_UNLIKELY(!(condition))) { \
GR_ERROR_RETURN(category, code, ret_val, format, ##__VA_ARGS__); \
} \
} while(0)
* Check NULL pointer and return error
* Usage: GR_CHECK_NULL_RETURN(ptr, GR_ERR_CATEGORY_PARAM, ERR_GR_INVALID_PARAM, CM_ERROR, "Pointer is NULL");
*/
#define GR_CHECK_NULL_RETURN(ptr, category, code, ret_val, format, ...) \
GR_CHECK_RETURN((ptr) != NULL, category, code, ret_val, format, ##__VA_ARGS__)
* Filesystem-specific error handling macros
*/
#define GR_FS_ERROR_RETURN(code, format, ...) \
GR_ERROR_RETURN(GR_ERR_CATEGORY_FILESYSTEM, code, CM_ERROR, format, ##__VA_ARGS__)
#define GR_FS_CHECK_RETURN(condition, code, format, ...) \
GR_CHECK_RETURN(condition, GR_ERR_CATEGORY_FILESYSTEM, code, CM_ERROR, format, ##__VA_ARGS__)
#define GR_FS_CHECK_NULL_RETURN(ptr, code, format, ...) \
GR_CHECK_NULL_RETURN(ptr, GR_ERR_CATEGORY_FILESYSTEM, code, CM_ERROR, format, ##__VA_ARGS__)
* Parameter validation error handling macros
*/
#define GR_PARAM_ERROR_RETURN(code, format, ...) \
GR_ERROR_RETURN(GR_ERR_CATEGORY_PARAM, code, CM_ERROR, format, ##__VA_ARGS__)
#define GR_PARAM_CHECK_RETURN(condition, code, format, ...) \
GR_CHECK_RETURN(condition, GR_ERR_CATEGORY_PARAM, code, CM_ERROR, format, ##__VA_ARGS__)
* System call error handling with errno
* Usage: GR_SYS_ERROR_RETURN("Failed to open file: %s", path);
*/
#define GR_SYS_ERROR_RETURN(format, ...) \
do { \
int _errno_save = errno; \
LOG_RUN_ERR("[SYSTEM] " format ", errno: %d (%s)", ##__VA_ARGS__, _errno_save, strerror(_errno_save)); \
GR_THROW_ERROR(ERR_GR_FILE_SYSTEM_ERROR); \
return CM_ERROR; \
} while(0)
* Function call error check and return
* Usage: GR_CALL_RETURN(func(), "Function call failed");
*/
#define GR_CALL_RETURN(func_call, format, ...) \
do { \
status_t _ret = (func_call); \
if (SECUREC_UNLIKELY(_ret != CM_SUCCESS)) { \
LOG_RUN_ERR(format ", status: %d", ##__VA_ARGS__, _ret); \
return _ret; \
} \
} while(0)
* Get error category name for logging
*/
const char *gr_err_category_name(gr_err_category_t category);
#ifdef __cplusplus
}
#endif
#endif