1251 lines
88 KiB
MQL5
1251 lines
88 KiB
MQL5
#ifndef LIB_ERROR_MAIN_CODE_MQH_INCLUDED
|
|
#define LIB_ERROR_MAIN_CODE_MQH_INCLUDED
|
|
#property version "4.0";
|
|
/**********************************************************************************
|
|
* Copyright (C) 2010-2020 Dominik Egert <dominik.egert@freie-netze.de>
|
|
*
|
|
* This file is part of lib_bali
|
|
*
|
|
* lib_error.mqh may be copied and/or distributed at free will
|
|
* Dominik Egert / Freie Netze UG.
|
|
**********************************************************************************
|
|
*
|
|
* Version 4.0
|
|
* State: public
|
|
*
|
|
*
|
|
* File information
|
|
* ================
|
|
*
|
|
* Use: resolve error codes to text
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
//
|
|
// Define library mode
|
|
//
|
|
|
|
// Header mode
|
|
#ifndef LIB_ERR_LIB_EXPORT
|
|
#define LIB_ERR_LIB_EXPORT
|
|
#endif
|
|
|
|
// Binary mode
|
|
#ifdef LIB_ERR_BINARY_LIBRARY
|
|
#ifndef LIB_ERR_NO_INCLUDE
|
|
#define LIB_ERR_NO_INCLUDE
|
|
#endif
|
|
|
|
#ifdef LIB_ERR_LIB_EXPORT
|
|
#undef LIB_ERR_LIB_EXPORT
|
|
#endif
|
|
|
|
#ifdef LIB_DEBUG
|
|
#undef LIB_DEBUG
|
|
#endif
|
|
|
|
#define LIB_ERR_LIB_EXPORT export
|
|
#property library
|
|
#endif
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
|
//
|
|
// Debugging support
|
|
//
|
|
|
|
//#define LIB_DEBUG
|
|
#ifdef LIB_DEBUG
|
|
#include <../Shared Projects/MQLplus/lib_debug.mqh>
|
|
#endif
|
|
|
|
|
|
///////////////////////////////////////
|
|
// Error resolver trace options
|
|
|
|
// Trace err_reg_resolver()
|
|
//#define DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
|
|
// Trace err_desc()
|
|
//#define DBG_TRACE_ERROR_ERR_DESC
|
|
|
|
// Trace err_desc_user
|
|
//#define DBG_TRACE_ERROR_ERR_DESC_USER
|
|
|
|
// Trace err_desc_comment
|
|
//#define DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
|
|
// Trace err_SetMqlError
|
|
//#define DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
|
|
// Trace err_SetUserError
|
|
//#define DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
|
|
// Trace err_ResetUserError
|
|
//#define DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
|
|
// Trace err_ResolveLastError
|
|
//#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
|
|
// Trace err_LastErrorCode
|
|
//#define DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
|
|
// Trace default OnError() handler
|
|
//#define DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
|
|
|
|
//
|
|
///////////////////////////////////////
|
|
|
|
//
|
|
// END Global error handler configuration
|
|
//*********************************************************************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************************************************/
|
|
// Macro definitions (no edit)
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Debug trace function call support
|
|
//
|
|
// Will only work when including lib_debug.mqh
|
|
//
|
|
#ifdef LIB_DEBUG
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Full trace
|
|
#ifdef DBG_TRACE_LIB_ERROR
|
|
#ifndef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#define DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC
|
|
#define DBG_TRACE_ERROR_ERR_DESC
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#define DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#define DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#define DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#define DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#endif
|
|
#endif
|
|
//
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Disable debugging support
|
|
#else
|
|
|
|
// Error code location string
|
|
#define DGB_CODE_LOCATION(x)
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Clear debug tracing at runtime
|
|
#ifdef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#undef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC
|
|
#undef DBG_TRACE_ERROR_ERR_DESC
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#undef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#undef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#undef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#undef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#undef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#undef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#undef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#endif
|
|
#ifdef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#undef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#endif
|
|
//
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
#endif
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// Minimum required debugging support
|
|
// in case lib_debug.mqh is not included.
|
|
//
|
|
|
|
// Include primitive debugging helpers
|
|
#ifndef DBG_ASSERT_RETURN_VAR
|
|
#define DBG_ASSERT_RETURN_VAR(cond, msg, retval) { if(!(cond)) { string _msg_ = StringFormat("%s>%s< %s(){ @%i: %s }", ((#cond == "") ? "" : #cond + " "), __FILE__, __FUNCTION__, __LINE__, msg); return(retval); } }
|
|
#endif
|
|
#ifndef DBG_MSG_TRACE_RETURN
|
|
#define DBG_MSG_TRACE_RETURN return
|
|
#endif
|
|
#ifndef DBG_MSG_TRACE_RETURN_VAR
|
|
#define DBG_MSG_TRACE_RETURN_VAR(x) return(x)
|
|
#endif
|
|
#ifndef DBG_MSG
|
|
#define DBG_MSG(x)
|
|
#endif
|
|
#ifndef DBG_MSG_PERSIST
|
|
#define DBG_MSG_PERSIST(x) printf("%s", x)
|
|
#endif
|
|
#ifndef DBG_MSG_VAR
|
|
#define DBG_MSG_VAR(x)
|
|
#endif
|
|
#ifndef PERF_COUNTER_BEGIN
|
|
#define PERF_COUNTER_BEGIN
|
|
#endif
|
|
#ifndef DBG_MSG_NOTRACE_RETURN
|
|
#define DBG_MSG_NOTRACE_RETURN return
|
|
#endif
|
|
#ifndef DBG_MSG_NOTRACE_RETURN_VAR
|
|
#define DBG_MSG_NOTRACE_RETURN_VAR(x) return(x)
|
|
#endif
|
|
//
|
|
////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//
|
|
// END Macro definitions (no edit)
|
|
//*********************************************************************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************************************************/
|
|
// Error handler (No editing needed beyond this line...)
|
|
//
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
namespace lib_err {// Namespace lib_err:: BEGIN
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////
|
|
//
|
|
// Database language router
|
|
//
|
|
|
|
// Language id generator
|
|
union str_char { uchar arr[sizeof(uint)]; uint id; } static lib_err_language;
|
|
#ifdef LIB_ERROR_DESCRIPTION_FROM_FILE
|
|
static int lib_err_language_id_bytes = StringToCharArray("FILE", lib_err_language.arr, NULL, sizeof(lib_err_language.id));
|
|
#else
|
|
static int lib_err_language_id_bytes = StringToCharArray(TerminalInfoString(TERMINAL_LANGUAGE), lib_err_language.arr, NULL, sizeof(lib_err_language.id));
|
|
#endif
|
|
|
|
// Primary error code resolver
|
|
const string LIB_ERR_NAMESPACE_DEF(lib_err, error_description)(const int error_code)
|
|
{
|
|
switch(lib_err_language.id)
|
|
{
|
|
// Read from file
|
|
#ifdef LIB_ERROR_DESCRIPTION_FROM_FILE
|
|
case LIB_ERROR_LANG_FROM_FILE:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_FROM_FILE);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_FROM_FILE)(error_code));
|
|
#endif
|
|
|
|
// Worldwide
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_RU
|
|
case LIB_ERROR_LANG_TERM_ID_RU:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_RU);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_RU)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_TR
|
|
case LIB_ERROR_LANG_TERM_ID_TR:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_TR);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_TR)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_ZH
|
|
case LIB_ERROR_LANG_TERM_ID_ZH:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_ZH);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_ZH)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_JP
|
|
case LIB_ERROR_LANG_TERM_ID_JP:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_JP);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_JP)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_KO
|
|
case LIB_ERROR_LANG_TERM_ID_KO:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_KO);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_KO)(error_code));
|
|
#endif
|
|
|
|
// Europe
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_ES
|
|
case LIB_ERROR_LANG_TERM_ID_ES:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_ES);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_ES)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_PT
|
|
case LIB_ERROR_LANG_TERM_ID_PT:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_PT);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_PT)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_FR
|
|
case LIB_ERROR_LANG_TERM_ID_FR:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_FR);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_FR)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_IT
|
|
case LIB_ERROR_LANG_TERM_ID_IT:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_IT);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_IT)(error_code));
|
|
#endif
|
|
|
|
#ifdef LIB_ERROR_LANG_TERM_ID_DE
|
|
case LIB_ERROR_LANG_TERM_ID_DE:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_DE);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_DE)(error_code));
|
|
#endif
|
|
|
|
// English as default
|
|
default:
|
|
LIB_ERR_NAMESPACE(lib_err, func_ptr_mql_err_codes) = LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_EN);
|
|
return(LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_EN)(error_code));
|
|
}
|
|
|
|
// Return error
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
// Language id to ALPHA-2 code
|
|
const string LIB_ERR_NAMESPACE_DEF(lib_err, error_language_alpha_code)()
|
|
{
|
|
switch(lib_err_language.id)
|
|
{
|
|
case LIB_ERROR_LANG_TERM_ID_RU: return("ru");
|
|
case LIB_ERROR_LANG_TERM_ID_TR: return("tr");
|
|
case LIB_ERROR_LANG_TERM_ID_ZH: return("cn");
|
|
case LIB_ERROR_LANG_TERM_ID_JP: return("jp");
|
|
case LIB_ERROR_LANG_TERM_ID_KO: return("kp");
|
|
case LIB_ERROR_LANG_TERM_ID_ES: return("es");
|
|
case LIB_ERROR_LANG_TERM_ID_PT: return("pl");
|
|
case LIB_ERROR_LANG_TERM_ID_FR: return("fr");
|
|
case LIB_ERROR_LANG_TERM_ID_IT: return("it");
|
|
case LIB_ERROR_LANG_TERM_ID_DE: return("de");
|
|
}
|
|
|
|
// Return default
|
|
return("en");
|
|
}
|
|
|
|
|
|
// Language specific error code resolver (english)
|
|
#ifdef LIB_ERROR_DESCRIPTION_FROM_FILE
|
|
const string LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_FROM_FILE)(const int error_code)
|
|
{
|
|
// Error structure
|
|
|
|
struct err_desc_struct
|
|
{
|
|
int err_code;
|
|
string err_name;
|
|
string err_desc;
|
|
|
|
err_desc_struct() :
|
|
err_code (-1),
|
|
err_name (NULL),
|
|
err_desc (NULL)
|
|
{ };
|
|
};
|
|
|
|
// Local init
|
|
|
|
static int arr_size = NULL;
|
|
int cnt = NULL;
|
|
static string filename = StringFormat("lib_error_descriptions_%s_%s.csv", LIB_ERR_MT_VERSION_ID_STRING, LIB_ERR_NAMESPACE(lib_err, error_language_alpha_code)());
|
|
static err_desc_struct local_err_desc_arr[];
|
|
|
|
|
|
// Read file, if exists
|
|
|
|
if( (arr_size == NULL)
|
|
&& (FileIsExist("lib_error_descriptions.csv")) )
|
|
{
|
|
ResetLastError();
|
|
const int h_file = FileOpen("lib_error_descriptions.csv", FILE_READ | FILE_COMMON | FILE_TXT, CP_UTF8);
|
|
bool abort = (_LastError != NULL);
|
|
ushort separator[1];
|
|
string f_line = NULL;
|
|
string split_value[];
|
|
StringToShortArray(";", separator, 0, 1);
|
|
|
|
|
|
while( (!FileIsEnding(h_file))
|
|
&& (!_StopFlag)
|
|
&& (!abort) )
|
|
{
|
|
// Get next line
|
|
ResetLastError();
|
|
f_line = FileReadString(h_file);
|
|
abort |= (_LastError != NULL);
|
|
|
|
// Split CSV values
|
|
if( (!abort)
|
|
&& (StringSplit(f_line, separator[0], split_value) == 3) )
|
|
{
|
|
arr_size = ArrayResize(local_err_desc_arr, arr_size + 1, 300);
|
|
local_err_desc_arr[arr_size - 1].err_code = StringToInteger(split_value[0]);
|
|
local_err_desc_arr[arr_size - 1].err_name = split_value[1];
|
|
local_err_desc_arr[arr_size - 1].err_desc = split_value[2];
|
|
}
|
|
}
|
|
|
|
is_init = (h_file != INVALID_HANDLE) && (!abort) && (arr_size > NULL);
|
|
FileClose(h_file);
|
|
arr_size = (abort) ? -1 : ArraySize(local_err_desc_arr);
|
|
}
|
|
|
|
|
|
// Find error description
|
|
|
|
while( (cnt < arr_size)
|
|
&& (local_err_desc_arr[cnt].err_code != error_code)
|
|
&& (!_StopFlag) )
|
|
{ cnt++; }
|
|
|
|
|
|
// Clear error codes
|
|
|
|
ResetLastError();
|
|
|
|
|
|
// Return
|
|
return((cnt < arr_size) ? LIB_ERR_OUTPUT_FORMAT(local_err_desc_arr.err_code, local_err_desc_arr.err_name, local_err_desc_arr.err_desc) : LIB_ERROR_LANGUAGE_FUNCTION(LIB_ERROR_LANG_TERM_ID_EN)(error_code));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
//////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////
|
|
//
|
|
// Global resolver array
|
|
//
|
|
|
|
// Mql error resolver functions
|
|
static TUsrErrFunc LIB_ERR_NAMESPACE_DEF(lib_err, func_ptr_mql_err_codes) = LIB_ERR_NAMESPACE(lib_err, error_description);
|
|
|
|
// Array error group resolver functions
|
|
static TUsrErrFunc LIB_ERR_NAMESPACE_DEF(lib_err, error_groups)[(0x10000 / LIB_ERR_GROUP_SIZE)];
|
|
|
|
//
|
|
//////////////////////////////////////////
|
|
|
|
|
|
|
|
//////////////////////////////////////////
|
|
//
|
|
// Global state storage
|
|
//
|
|
|
|
// Internal error code variable
|
|
static int LIB_ERR_NAMESPACE_DEF(lib_err, _err_last_error_code) = -1;
|
|
|
|
// Last resolved error code
|
|
static int LIB_ERR_NAMESPACE_DEF(lib_err, _last_resolved_code) = NULL;
|
|
|
|
// Additional error comment handling
|
|
static string LIB_ERR_NAMESPACE_DEF(lib_err, _intern_err_comment) = "";
|
|
|
|
//
|
|
//////////////////////////////////////////
|
|
|
|
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* Error code resolver *
|
|
*********************************************************************************************************
|
|
*/
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| err_desc() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC
|
|
#undef DBG_TRACE_ERROR_ERR_DESC
|
|
#define DBG_TRACE_ERROR_ERR_DESC(x) x
|
|
#define DBG_TRACE_ERROR_ERR_DESC_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC
|
|
#define DBG_TRACE_ERROR_ERR_DESC(x)
|
|
#define DBG_TRACE_ERROR_ERR_DESC_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
const string LIB_ERR_NAMESPACE_DEF(lib_err, err_desc)(const int err_code = -1, const string txt_prefix = NULL)
|
|
{
|
|
DBG_TRACE_ERROR_ERR_DESC(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(err_code);
|
|
DBG_MSG_VAR(txt_prefix);
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Local init
|
|
|
|
int error_code = err_code;
|
|
int cur_api_err_code = _LastError;
|
|
string error_string = NULL;
|
|
|
|
DBG_TRACE_ERROR_ERR_DESC(
|
|
DBG_MSG_VAR(error_code);
|
|
DBG_MSG_VAR(cur_api_err_code);
|
|
);
|
|
|
|
|
|
// Check error code input
|
|
|
|
if(error_code < 0)
|
|
{
|
|
if(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) > -1)
|
|
{
|
|
error_code = (int)LIB_ERR_NAMESPACE(lib_err, _err_last_error_code);
|
|
LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) = -1;
|
|
}
|
|
|
|
if(cur_api_err_code > 0)
|
|
{
|
|
error_code = cur_api_err_code;
|
|
ResetLastError();
|
|
}
|
|
|
|
if( (cur_api_err_code == NULL)
|
|
&& (error_code < 1))
|
|
{ error_code = NULL; }
|
|
}
|
|
|
|
|
|
// Resolve user defined error codes
|
|
|
|
if((error_code >= ERR_USER_ERROR_FIRST) && (error_code <= ERR_USER_ERROR_LAST))
|
|
{ error_string = StringFormat("%s %s", LIB_ERR_NAMESPACE(lib_err, err_desc_user)(error_code), LIB_ERR_NAMESPACE(lib_err, err_desc_comment)()); }
|
|
|
|
|
|
// Resolve MQL API error codes
|
|
|
|
else
|
|
{ error_string = func_ptr_mql_err_codes(error_code); }
|
|
|
|
|
|
// Add comment if given
|
|
|
|
if( (txt_prefix != "")
|
|
&& (txt_prefix != NULL))
|
|
{ error_string = (StringLen(txt_prefix) == NULL) ? error_string : StringFormat("%s: %s", txt_prefix, error_string); }
|
|
|
|
|
|
// Save last resolved error code
|
|
|
|
LIB_ERR_NAMESPACE(lib_err, _last_resolved_code) = error_code;
|
|
|
|
|
|
// Return resolved error text
|
|
DBG_TRACE_ERROR_ERR_DESC_RETURN(error_string);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| err_desc_user() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#undef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#define DBG_TRACE_ERROR_ERR_DESC_USER(x) x
|
|
#define DBG_TRACE_ERROR_ERR_DESC_USER_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC_USER
|
|
#define DBG_TRACE_ERROR_ERR_DESC_USER(x)
|
|
#define DBG_TRACE_ERROR_ERR_DESC_USER_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
const string LIB_ERR_NAMESPACE_DEF(lib_err, err_desc_user)(const int error_code)
|
|
{
|
|
DBG_TRACE_ERROR_ERR_DESC_USER(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(error_code);
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Check group id state
|
|
if(error_groups[(uchar)(error_code >> 0x08)] == NULL)
|
|
{ DBG_TRACE_ERROR_ERR_DESC_USER_RETURN(StringFormat("(%i - %s) %s: %i", error_code, "ERR_USER_ERROR", "Unknown error code. No router for group id", (error_code >> 0x08))); }
|
|
|
|
// Resolve error code to message
|
|
TUsrErrFunc func_ptr = error_groups[(uchar)(error_code >> 0x08)];
|
|
string retval = func_ptr(error_code);
|
|
|
|
// Return result
|
|
if(StringLen(retval) > 2)
|
|
{ DBG_TRACE_ERROR_ERR_DESC_USER_RETURN(retval); }
|
|
|
|
// Return unknown error code
|
|
DBG_TRACE_ERROR_ERR_DESC_USER_RETURN(StringFormat("(%i - %s) %s", error_code, "ERR_USER_ERROR", "A description is not available."));
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| err_desc_comment() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#undef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#define DBG_TRACE_ERROR_ERR_DESC_COMMENT(x) x
|
|
#define DBG_TRACE_ERROR_ERR_DESC_COMMENT_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_DESC_COMMENT
|
|
#define DBG_TRACE_ERROR_ERR_DESC_COMMENT(x)
|
|
#define DBG_TRACE_ERROR_ERR_DESC_COMMENT_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
const string LIB_ERR_NAMESPACE_DEF(lib_err, err_desc_comment)(const string comment = NULL)
|
|
{
|
|
DBG_TRACE_ERROR_ERR_DESC_USER(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(comment);
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Store new or additional comment
|
|
if(comment != NULL)
|
|
{
|
|
LIB_ERR_NAMESPACE(lib_err, _intern_err_comment) = StringFormat("%s %s", (LIB_ERR_NAMESPACE(lib_err, _intern_err_comment) == NULL) ? "" : LIB_ERR_NAMESPACE(lib_err, _intern_err_comment), (comment == NULL) ? "" : comment);
|
|
if(StringSubstr(comment, NULL, 2) != "\r\n")
|
|
{ StringTrimLeft(LIB_ERR_NAMESPACE(lib_err, _intern_err_comment)); }
|
|
StringTrimRight(LIB_ERR_NAMESPACE(lib_err, _intern_err_comment));
|
|
}
|
|
|
|
// Retrieve and clear stored comment
|
|
else if(StringLen(LIB_ERR_NAMESPACE(lib_err, _intern_err_comment)) > 1)
|
|
{
|
|
string tmp = " " + LIB_ERR_NAMESPACE(lib_err, _intern_err_comment);
|
|
LIB_ERR_NAMESPACE(lib_err, _intern_err_comment) = NULL;
|
|
DBG_TRACE_ERROR_ERR_DESC_COMMENT_RETURN(tmp);
|
|
}
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_DESC_COMMENT_RETURN("");
|
|
}
|
|
|
|
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
}; // Namespace lib_err:: END
|
|
#endif
|
|
//
|
|
// END Error handler
|
|
//*********************************************************************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************************************************/
|
|
// Extended version of original MQL API error functions
|
|
//
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
namespace LibError { // Namespace LibError:: BEGIN
|
|
|
|
#endif
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| RegisterErrorCodeResolver() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#undef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#define DBG_TRACE_ERROR_ERR_REG_RESOLVER(x) x
|
|
#define DBG_TRACE_ERROR_ERR_REG_RESOLVER_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#else
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_REG_RESOLVER
|
|
#define DBG_TRACE_ERROR_ERR_REG_RESOLVER(x)
|
|
#define DBG_TRACE_ERROR_ERR_REG_RESOLVER_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
bool LIB_ERR_NAMESPACE_DEF(LibError, RegisterErrorCodeResolver)(const ushort group_id, const TUsrErrFunc resolver_func_ptr) LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_REG_RESOLVER(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(group_id);
|
|
DBG_MSG_VAR((resolver_func_ptr != NULL));
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Static init
|
|
static bool init = false;
|
|
|
|
// Local init
|
|
uchar _grp_id = (uchar)((group_id > 0xFF) ? (group_id >> 0x08) : group_id);
|
|
|
|
DBG_TRACE_ERROR_ERR_REG_RESOLVER(
|
|
DBG_MSG_VAR(init);
|
|
DBG_MSG_VAR(_grp_id);
|
|
);
|
|
|
|
// Check init state
|
|
if(!init)
|
|
{
|
|
ZeroMemory(LIB_ERR_NAMESPACE(lib_err, error_groups));
|
|
init = true;
|
|
}
|
|
|
|
// Debug: Compile error (group_ids must be unique)
|
|
DBG_ASSERT_RETURN_VAR((LIB_ERR_NAMESPACE(lib_err, error_groups)[_grp_id] == NULL), StringFormat("Error: Group ID %i assigned! Check parameter 1 from macro 'LIB_ERR_REGISTER_RESOLVER_BEGIN / _END'", _grp_id), false);
|
|
|
|
// Create new message router
|
|
LIB_ERR_NAMESPACE(lib_err, error_groups)[_grp_id] = resolver_func_ptr;
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_REG_RESOLVER_RETURN(true);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| SetMqlErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#undef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETMQLERROR(x) x
|
|
#define DBG_TRACE_ERROR_ERR_SETMQLERROR_RETURN DBG_MSG_TRACE_RETURN
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_SETMQLERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETMQLERROR(x)
|
|
#define DBG_TRACE_ERROR_ERR_SETMQLERROR_RETURN DBG_MSG_NOTRACE_RETURN
|
|
#endif
|
|
/////////////////////////////////////
|
|
void LIB_ERR_NAMESPACE_DEF(LibError, SetMqlErrorCode)( const uint err_code,
|
|
const string comment = "",
|
|
const string comment1 = "",
|
|
const string comment2 = "",
|
|
const string comment3 = "",
|
|
const string comment4 = "",
|
|
const string comment5 = "",
|
|
const string comment6 = "",
|
|
const string comment7 = "",
|
|
const string comment8 = "",
|
|
const string comment9 = "",
|
|
const string commentA = "",
|
|
const string commentB = "",
|
|
const string commentC = "",
|
|
const string commentD = "",
|
|
const string commentE = "",
|
|
const string commentF = "") LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_SETMQLERROR(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(err_code);
|
|
DBG_MSG_VAR(comment);
|
|
DBG_MSG_VAR(comment1);
|
|
DBG_MSG_VAR(comment2);
|
|
DBG_MSG_VAR(comment3);
|
|
DBG_MSG_VAR(comment4);
|
|
DBG_MSG_VAR(comment5);
|
|
DBG_MSG_VAR(comment6);
|
|
DBG_MSG_VAR(comment7);
|
|
DBG_MSG_VAR(comment8);
|
|
DBG_MSG_VAR(comment9);
|
|
DBG_MSG_VAR(commentA);
|
|
DBG_MSG_VAR(commentB);
|
|
DBG_MSG_VAR(commentC);
|
|
DBG_MSG_VAR(commentD);
|
|
DBG_MSG_VAR(commentE);
|
|
DBG_MSG_VAR(commentF);
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Local init
|
|
string concat = StringFormat("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
((comment1 != "") && (comment1 != NULL) ? "\r\n |=> " : "") + comment,
|
|
((comment1 != "") && (comment1 != NULL) ? "\r\n |=> " + comment1 : ""),
|
|
((comment2 != "") && (comment2 != NULL) ? "\r\n |=> " + comment2 : ""),
|
|
((comment3 != "") && (comment3 != NULL) ? "\r\n |=> " + comment3 : ""),
|
|
((comment4 != "") && (comment4 != NULL) ? "\r\n |=> " + comment4 : ""),
|
|
((comment5 != "") && (comment5 != NULL) ? "\r\n |=> " + comment5 : ""),
|
|
((comment6 != "") && (comment6 != NULL) ? "\r\n |=> " + comment6 : ""),
|
|
((comment7 != "") && (comment7 != NULL) ? "\r\n |=> " + comment7 : ""),
|
|
((comment8 != "") && (comment8 != NULL) ? "\r\n |=> " + comment8 : ""),
|
|
((comment9 != "") && (comment9 != NULL) ? "\r\n |=> " + comment9 : ""),
|
|
((commentA != "") && (commentA != NULL) ? "\r\n |=> " + commentA : ""),
|
|
((commentB != "") && (commentB != NULL) ? "\r\n |=> " + commentB : ""),
|
|
((commentC != "") && (commentC != NULL) ? "\r\n |=> " + commentC : ""),
|
|
((commentD != "") && (commentD != NULL) ? "\r\n |=> " + commentD : ""),
|
|
((commentE != "") && (commentE != NULL) ? "\r\n |=> " + commentE : ""),
|
|
((commentF != "") && (commentF != NULL) ? "\r\n |=> " + commentF : ""));
|
|
|
|
DBG_TRACE_ERROR_ERR_SETMQLERROR(
|
|
DBG_MSG_VAR(short_code);
|
|
DBG_MSG_VAR(concat);
|
|
);
|
|
|
|
|
|
// Set comment, if supplied
|
|
LIB_ERR_NAMESPACE(lib_err, err_desc_comment)(concat);
|
|
|
|
// Set error code
|
|
LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) = (int)err_code;
|
|
|
|
DBG_TRACE_ERROR_ERR_SETMQLERROR(
|
|
DBG_MSG_VAR(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code));
|
|
DBG_MSG_VAR(LIB_ERR_NAMESPACE(lib_err, err_desc)(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code)));
|
|
);
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_SETMQLERROR_RETURN;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| SetUserErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#undef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETUSERERROR(x) x
|
|
#define DBG_TRACE_ERROR_ERR_SETUSERERROR_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_SETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_SETUSERERROR(x)
|
|
#define DBG_TRACE_ERROR_ERR_SETUSERERROR_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
bool LIB_ERR_NAMESPACE_DEF(LibError, SetUserErrorCode)(const uint err_code,
|
|
const string comment = "",
|
|
const string comment1 = "",
|
|
const string comment2 = "",
|
|
const string comment3 = "",
|
|
const string comment4 = "",
|
|
const string comment5 = "",
|
|
const string comment6 = "",
|
|
const string comment7 = "",
|
|
const string comment8 = "",
|
|
const string comment9 = "",
|
|
const string commentA = "",
|
|
const string commentB = "",
|
|
const string commentC = "",
|
|
const string commentD = "",
|
|
const string commentE = "",
|
|
const string commentF = "") LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_SETUSERERROR(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(err_code);
|
|
DBG_MSG_VAR(comment);
|
|
DBG_MSG_VAR(comment1);
|
|
DBG_MSG_VAR(comment2);
|
|
DBG_MSG_VAR(comment3);
|
|
DBG_MSG_VAR(comment4);
|
|
DBG_MSG_VAR(comment5);
|
|
DBG_MSG_VAR(comment6);
|
|
DBG_MSG_VAR(comment7);
|
|
DBG_MSG_VAR(comment8);
|
|
DBG_MSG_VAR(comment9);
|
|
DBG_MSG_VAR(commentA);
|
|
DBG_MSG_VAR(commentB);
|
|
DBG_MSG_VAR(commentC);
|
|
DBG_MSG_VAR(commentD);
|
|
DBG_MSG_VAR(commentE);
|
|
DBG_MSG_VAR(commentF);
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Local init
|
|
const ushort short_code = (ushort)err_code;
|
|
string concat = StringFormat("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
|
((comment1 != "") && (comment1 != NULL) ? "\r\n |=> " : "") + comment,
|
|
((comment1 != "") && (comment1 != NULL) ? "\r\n |=> " + comment1 : ""),
|
|
((comment2 != "") && (comment2 != NULL) ? "\r\n |=> " + comment2 : ""),
|
|
((comment3 != "") && (comment3 != NULL) ? "\r\n |=> " + comment3 : ""),
|
|
((comment4 != "") && (comment4 != NULL) ? "\r\n |=> " + comment4 : ""),
|
|
((comment5 != "") && (comment5 != NULL) ? "\r\n |=> " + comment5 : ""),
|
|
((comment6 != "") && (comment6 != NULL) ? "\r\n |=> " + comment6 : ""),
|
|
((comment7 != "") && (comment7 != NULL) ? "\r\n |=> " + comment7 : ""),
|
|
((comment8 != "") && (comment8 != NULL) ? "\r\n |=> " + comment8 : ""),
|
|
((comment9 != "") && (comment9 != NULL) ? "\r\n |=> " + comment9 : ""),
|
|
((commentA != "") && (commentA != NULL) ? "\r\n |=> " + commentA : ""),
|
|
((commentB != "") && (commentB != NULL) ? "\r\n |=> " + commentB : ""),
|
|
((commentC != "") && (commentC != NULL) ? "\r\n |=> " + commentC : ""),
|
|
((commentD != "") && (commentD != NULL) ? "\r\n |=> " + commentD : ""),
|
|
((commentE != "") && (commentE != NULL) ? "\r\n |=> " + commentE : ""),
|
|
((commentF != "") && (commentF != NULL) ? "\r\n |=> " + commentF : ""));
|
|
//StringTrimRight(concat);
|
|
|
|
DBG_TRACE_ERROR_ERR_SETUSERERROR(
|
|
DBG_MSG_VAR(short_code);
|
|
DBG_MSG_VAR(concat);
|
|
);
|
|
|
|
// Set comment, if supplied
|
|
LIB_ERR_NAMESPACE(lib_err, err_desc_comment)(concat);
|
|
|
|
// Set error code
|
|
LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) = short_code + ERR_USER_ERROR_FIRST;
|
|
ResetLastError();
|
|
SetUserError(short_code);
|
|
|
|
DBG_TRACE_ERROR_ERR_SETUSERERROR(
|
|
DBG_MSG_VAR(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code));
|
|
DBG_MSG_VAR(LIB_ERR_NAMESPACE(lib_err, err_desc)(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code)));
|
|
);
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_SETUSERERROR_RETURN((err_code & 0x0000FFFF) != NULL);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| ResetUserErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#undef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESETUSERERROR(x) x
|
|
#define DBG_TRACE_ERROR_ERR_RESETUSERERROR_RETURN DBG_MSG_TRACE_RETURN
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_RESETUSERERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESETUSERERROR(x)
|
|
#define DBG_TRACE_ERROR_ERR_RESETUSERERROR_RETURN DBG_MSG_NOTRACE_RETURN
|
|
#endif
|
|
/////////////////////////////////////
|
|
void LIB_ERR_NAMESPACE_DEF(LibError, ResetUserErrorCode)() LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_RESETUSERERROR(
|
|
DBG_MSG_TRACE_BEGIN;
|
|
DBG_MSG_VAR(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code));
|
|
);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Reset error code
|
|
|
|
LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) = -1;
|
|
LIB_ERR_NAMESPACE(lib_err, err_desc_comment)();
|
|
ResetLastError();
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_RESETUSERERROR_RETURN;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| ResolveLastErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#undef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(x) x
|
|
#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#else
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_RESOLVELASTERROR
|
|
#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(x)
|
|
#define DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
|
|
int LIB_ERR_NAMESPACE_DEF(LibError, ResolveLastErrorCode)(string& error_msg) LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Resolve code to text
|
|
error_msg = LIB_ERR_NAMESPACE(lib_err, err_desc)();
|
|
|
|
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_VAR(error_msg));
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(LIB_ERR_NAMESPACE(lib_err, _last_resolved_code));
|
|
}
|
|
|
|
string LIB_ERR_NAMESPACE_DEF(LibError, ResolveLastErrorCode)() LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Resolve and return
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(LIB_ERR_NAMESPACE(lib_err, err_desc)());
|
|
}
|
|
|
|
string LIB_ERR_NAMESPACE_DEF(LibError, ResolveLastErrorCode)(int& error_code) LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Local init
|
|
const string error_msg = LIB_ERR_NAMESPACE(lib_err, err_desc)();
|
|
|
|
// Resolve error
|
|
error_code = LIB_ERR_NAMESPACE(lib_err, _last_resolved_code);
|
|
|
|
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_VAR(error_msg));
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_VAR(error_code));
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(error_msg);
|
|
}
|
|
|
|
string LIB_ERR_NAMESPACE_DEF(LibError, ResolveLastErrorCode)(const int err_no, const string prefix) LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Resolve and return
|
|
DBG_TRACE_ERROR_ERR_RESOLVELASTERROR_RETURN(LIB_ERR_NAMESPACE(lib_err, err_desc)(err_no, prefix));
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| GetLastResolvedErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR
|
|
#undef DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR
|
|
#define DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR(x) x
|
|
#define DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR
|
|
#define DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR(x)
|
|
#define DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
int LIB_ERR_NAMESPACE_DEF(LibError, GetLastResolvedErrorCode)() LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_LASTRESOLVEDERROR_RETURN((LIB_ERR_NAMESPACE(lib_err, _last_resolved_code) == -1) ? ERR_SUCCESS : LIB_ERR_NAMESPACE(lib_err, _last_resolved_code));
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| GetLastErrorCode() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#undef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#define DBG_TRACE_ERROR_ERR_LASTERRORCODE(x) x
|
|
#define DBG_TRACE_ERROR_ERR_LASTERRORCODE_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_ERR_LASTERRORCODE
|
|
#define DBG_TRACE_ERROR_ERR_LASTERRORCODE(x)
|
|
#define DBG_TRACE_ERROR_ERR_LASTERRORCODE_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
int LIB_ERR_NAMESPACE_DEF(LibError, GetLastErrorCode)() LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_ERR_LASTERRORCODE(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Check current state
|
|
if(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) <= ERR_SUCCESS)
|
|
{
|
|
// Resolve error code
|
|
LIB_ERR_NAMESPACE(lib_err, err_desc)(-1);
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_LASTERRORCODE_RETURN(LIB_ERR_NAMESPACE(lib_err, _last_resolved_code));
|
|
}
|
|
|
|
// Return
|
|
DBG_TRACE_ERROR_ERR_LASTERRORCODE_RETURN(LIB_ERR_NAMESPACE(lib_err, _err_last_error_code));
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| DefaultOnError() |
|
|
//+------------------------------------------------------------------+
|
|
/////////////////////////////////////////////////////////
|
|
//
|
|
// DefaultOnError() Function
|
|
//
|
|
// Generic error handling function.
|
|
// Some return codes are not of interest, so
|
|
// they get sorted out here and are
|
|
// surpressed of being journaled.
|
|
//
|
|
#ifndef LIB_ERR_USER_ERROR_HANDLER
|
|
#define LIB_ERR_DEFAULT_HANDLER
|
|
/////////////////////////////////////
|
|
// Function debug trace code
|
|
#ifdef LIB_DEBUG
|
|
#ifdef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#undef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#define DBG_TRACE_ERROR_DEFAULT_ONERROR(x) x
|
|
#define DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x)
|
|
#endif
|
|
#endif
|
|
#ifndef DBG_TRACE_ERROR_DEFAULT_ONERROR
|
|
#define DBG_TRACE_ERROR_DEFAULT_ONERROR(x)
|
|
#define DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x)
|
|
#endif
|
|
/////////////////////////////////////
|
|
const bool LIB_ERR_NAMESPACE_DEF(LibError, DefaultOnError)(uint& err_no, const string prefix = NULL) LIB_ERR_LIB_EXPORT
|
|
{
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR(DBG_MSG_TRACE_BEGIN);
|
|
PERF_COUNTER_BEGIN;
|
|
|
|
// Local init
|
|
#ifdef LIB_DEBUG
|
|
const static bool exec_env = false;
|
|
#else
|
|
const static bool exec_env = (MQLInfoInteger(MQL_PROFILER) || MQLInfoInteger(MQL_FORWARD) || MQLInfoInteger(MQL_OPTIMIZATION) || MQLInfoInteger(MQL_FRAME_MODE)) && (!MQLInfoInteger(MQL_VISUAL_MODE) || !MQLInfoInteger(MQL_DEBUG));
|
|
#endif
|
|
err_no = (uint)_LastError;
|
|
const uint err = (err_no > NULL) ? err_no : ((LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) < NULL) ? NULL : LIB_ERR_NAMESPACE(lib_err, _err_last_error_code));
|
|
const uint err_mask = 0x000000FF | (0x0000FF00 * (((err & 0xFFFF0000) == NULL) & 0x00000001));
|
|
const bool err_warn = ((err & LIB_ERR_LEVEL_WARNING) == LIB_ERR_LEVEL_WARNING);
|
|
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR(
|
|
DBG_MSG_VAR(err)
|
|
);
|
|
|
|
|
|
// Success code
|
|
if((err & err_mask) == ERR_SUCCESS)
|
|
{
|
|
// Reset error code
|
|
LIB_ERR_NAMESPACE(lib_err, _err_last_error_code) = -1;
|
|
ResetUserErrorCode();
|
|
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(false);
|
|
}
|
|
|
|
// Warnings
|
|
else if((err_mask == 0x000000FF) && ((err & LIB_ERR_LEVEL_WARNING) == LIB_ERR_LEVEL_WARNING))
|
|
#ifdef LIB_ERR_LEVEL_WARNING_AS_ERROR
|
|
{
|
|
printf("%s", LIB_ERR_NAMESPACE(lib_err, err_desc)(-1, prefix));
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(true);
|
|
}
|
|
#else
|
|
{
|
|
printf("%s", LIB_ERR_NAMESPACE(lib_err, err_desc)(-1, prefix));
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(false);
|
|
}
|
|
#endif
|
|
|
|
// Handled error codes show as error or are given as non error, depending on execution environment
|
|
else if( (exec_env)
|
|
|| ((err_mask == 0x000000FF) && ((err & LIB_ERR_LEVEL_HANDLED_ERROR) == LIB_ERR_LEVEL_HANDLED_ERROR)))
|
|
{ DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(!exec_env); }
|
|
|
|
// Resolve and print error message
|
|
printf("%s", LIB_ERR_NAMESPACE(lib_err, err_desc)(-1, prefix));
|
|
|
|
// Return error state
|
|
DBG_TRACE_ERROR_DEFAULT_ONERROR_RETURN(true);
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifndef __MQL4_COMPATIBILITY_CODE__
|
|
}; // Namespace LibError:: END
|
|
#endif
|
|
//
|
|
// END Extended version of original MQL API SetUserError()
|
|
//*********************************************************************************************************************************************************/
|
|
|
|
/**************************************/
|
|
#endif // LIB_ERROR_MAIN_CODE_MQH_INCLUDED
|