MQLplus/lib_error/lib_error_main.mqh
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

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