//
// File: hzError.cpp
//
// Legal Notice: This file is part of the HadronZoo C++ Class Library. Copyright 2025 HadronZoo Project (http://www.hadronzoo.com)
//
// The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// The HadronZoo C++ Class Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses.
//
//
// Error reporting and logging functions.
//
#include <cstdarg>
#include <iostream>
#include <unistd.h>
#include <sys/sem.h>
#include <errno.h>
#include <execinfo.h>
#include "hzChars.h"
#include "hzChain.h"
#include "hzErrcode.h"
#include "hzProcess.h"
/*
** General system errors
*/
#define HZERR_OK 0 // Everything is hunky dory
#define HZERR_ARGUMENT 1001 // Bad or missing argument
#define HZERR_TYPE 1002 // Data Type not valid or not appropriate in this context
#define HZERR_FORMAT 1003 // Incorrect data or string format
#define HZERR_RANGE 1004 // Value out of range
#define HZERR_BADVALUE 1005 // Illegal value for type
#define HZERR_BADCALL 1006 // Illegal value for type
global const hzEcode E_OK (HZERR_OK) ; // Everything is hunky dory
global const hzEcode E_ARGUMENT (HZERR_ARGUMENT) ; // Bad argument
global const hzEcode E_TYPE (HZERR_TYPE) ; // Data Type not valid or not appropriate in this context
global const hzEcode E_FORMAT (HZERR_FORMAT) ; // Incorrect data or string format
global const hzEcode E_RANGE (HZERR_RANGE) ; // Value out of range
global const hzEcode E_BADVALUE (HZERR_BADVALUE) ; // Illegal value for type
global const hzEcode E_BADCALL (HZERR_BADCALL) ; // Incorrect function call or wrong state
static const char* hzerr_OK = "0000 E_OK" ;
static const char* hzerr_ARGUMENT = "1001 E_ARGUMENT" ;
static const char* hzerr_TYPE = "1002 E_TYPE" ;
static const char* hzerr_FORMAT = "1003 E_FORMAT" ;
static const char* hzerr_RANGE = "1004 E_RANGE" ;
static const char* hzerr_BADVALUE = "1005 E_BADVALUE" ;
static const char* hzerr_BADCALL = "1006 E_BADCALL" ;
/*
** Confilcts when setting values
*/
#define HZERR_INITFAIL 1011 // Initialization failed
#define HZERR_INITDUP 1012 // Resource already initialized
#define HZERR_NOINIT 1013 // Resource not initialized
#define HZERR_SETONCE 1014 // A variable that can only be set once, has already been set
#define HZERR_EXCLUDE 1015 // Exclusive resource already in use
#define HZERR_CONFLICT 1016 // Attempt to define object in doublespeak
#define HZERR_SEQUENCE 1017 // Call out of sequence
global const hzEcode E_INITFAIL (HZERR_INITFAIL) ; // Initialization failed
global const hzEcode E_INITDUP (HZERR_INITDUP) ; // Resource already initialized
global const hzEcode E_NOINIT (HZERR_NOINIT) ; // Resource not initialized
global const hzEcode E_SETONCE (HZERR_SETONCE) ; // A variable that can only be set once, has already been set
global const hzEcode E_EXCLUDE (HZERR_EXCLUDE) ; // Exclusive resource already in use
global const hzEcode E_CONFLICT (HZERR_CONFLICT) ; // Attempt to define object in doublespeak
global const hzEcode E_SEQUENCE (HZERR_SEQUENCE) ; // Call out of sequence
static const char* hzerr_INITFAIL = "1011 E_INITFAI" ;
static const char* hzerr_INITDUP = "1012 E_INITDUP" ;
static const char* hzerr_NOINIT = "1013 E_NOINIT" ;
static const char* hzerr_SETONCE = "1014 E_SETONCE" ;
static const char* hzerr_EXCLUDE = "1015 E_EXCLUDE" ;
static const char* hzerr_CONFLICT = "1016 E_CONFLICT" ;
static const char* hzerr_SEQUENCE = "1017 E_SEQUENCE" ;
/*
** Database errors
*/
#define HZERR_DUPLICATE 1021 // Illegal duplicate or redefinition
#define HZERR_NODATA 1022 // No data or empty file
#define HZERR_NOTFOUND 1023 // Item not found or search criteria resulted in 0 rows
#define HZERR_INSERT 1024 // Could not insert data
#define HZERR_DELETE 1025 // Could not delete data
#define HZERR_CORRUPT 1026 // Database, index or tree is corrupted
global const hzEcode E_DUPLICATE (HZERR_DUPLICATE) ; // Illegal duplicate or redefinition
global const hzEcode E_NODATA (HZERR_NODATA) ; // No data or empty file
global const hzEcode E_NOTFOUND (HZERR_NOTFOUND) ; // Item not found or search criteria resulted in 0 rows
global const hzEcode E_INSERT (HZERR_INSERT) ; // Could not insert data
global const hzEcode E_DELETE (HZERR_DELETE) ; // Could not delete data
global const hzEcode E_CORRUPT (HZERR_CORRUPT) ; // Database, index or tree is corrupted
static const char* hzerr_DUPLICATE = "1021 E_DUPLICATE" ;
static const char* hzerr_NODATA = "1022 E_NODATA" ;
static const char* hzerr_NOTFOUND = "1023 E_NOTFOUND" ;
static const char* hzerr_INSERT = "1024 E_INSERT" ;
static const char* hzerr_DELETE = "1025 E_DELETE" ;
static const char* hzerr_CORRUPT = "1026 E_CORRUPT" ;
/*
** Expressions
*/
#define HZERR_PARSE 1031 // Cannot parse expression
#define HZERR_SYNTAX 1032 // Syntax error in expression
global const hzEcode E_PARSE (HZERR_PARSE) ; // Cannot parse expression
global const hzEcode E_SYNTAX (HZERR_SYNTAX) ; // Syntax error in expression
static const char* hzerr_PARSE = "1031 E_PARSE" ;
static const char* hzerr_SYNTAX = "1032 E_SYNTAX" ;
/*
** System resources
*/
#define HZERR_NOCREATE 1041 // Failed to create a resorce (could be file or other data source)
#define HZERR_OPENFAIL 1042 // Failed to open a resorce (could be file or other data source)
#define HZERR_NOTOPEN 1043 // Resource is not open
#define HZERR_READFAIL 1044 // Read operation failed
#define HZERR_WRITEFAIL 1045 // Write operation failed
#define HZERR_MEMORY 1046 // Out of memory
#define HZERR_OVERFLOW 1047 // Buffer overflowed
global const hzEcode E_NOCREATE (HZERR_NOCREATE) ; // Failed to create a resorce = could be file or other data source
global const hzEcode E_OPENFAIL (HZERR_OPENFAIL) ; // Failed to open a resorce = could be file or other data source
global const hzEcode E_NOTOPEN (HZERR_NOTOPEN) ; // Resource is not open
global const hzEcode E_READFAIL (HZERR_READFAIL) ; // Read operation failed
global const hzEcode E_WRITEFAIL (HZERR_WRITEFAIL) ; // Write operation failed
global const hzEcode E_MEMORY (HZERR_MEMORY) ; // Out of memory
global const hzEcode E_OVERFLOW (HZERR_OVERFLOW) ; // Buffer overflowed
static const char* hzerr_NOCREATE = "1041 E_NOCREATE" ;
static const char* hzerr_OPENFAIL = "1042 E_OPENFAIL" ;
static const char* hzerr_NOTOPEN = "1043 E_NOTOPEN" ;
static const char* hzerr_READFAIL = "1044 E_READFAIL" ;
static const char* hzerr_WRITEFAIL = "1045 E_WRITEFAIL" ;
static const char* hzerr_MEMORY = "1046 E_MEMORY" ;
static const char* hzerr_OVERFLOW = "1047 E_OVERFLOW" ;
/*
** DNS errors
*/
#define HZERR_DNS_NOHOST 1051 // The domain exists but no data was obtained
#define HZERR_DNS_NODATA 1052 // The domain exists but no data was obtained
#define HZERR_DNS_RETRY 1053 // End this server session and try again int16_tly
#define HZERR_DNS_FAILED 1054 // Something terrible is wrong with the DNS
global const hzEcode E_DNS_NOHOST (HZERR_DNS_NOHOST) ; // The domain does not exist
global const hzEcode E_DNS_NODATA (HZERR_DNS_NODATA) ; // The domain exists but no data obtained
global const hzEcode E_DNS_RETRY (HZERR_DNS_RETRY) ; // Timeout, please retry
global const hzEcode E_DNS_FAILED (HZERR_DNS_FAILED) ; // DNS failed
static const char* hzerr_DNS_NOHOST = "1051 E_DNS_NOHOST" ;
static const char* hzerr_DNS_NODATA = "1052 E_DNS_NODATA" ;
static const char* hzerr_DNS_RETRY = "1053 E_DNS_RETRY" ;
static const char* hzerr_DNS_FAILED = "1054 E_DNS_FAILED" ;
/*
** Comms
*/
#define HZERR_NOSOCKET 1061 // Cannot get a TCP/IP socket
#define HZERR_HOSTFAIL 1062 // Cannot get host by name
#define HZERR_HOSTRETRY 1063 // Host server accepts connections, states it is busy and closes connection
#define HZERR_SENDFAIL 1064 // Cannot send to host (socket error)
#define HZERR_RECVFAIL 1065 // Cannot recv from host (socket error)
#define HZERR_PROTOCOL 1066 // Client/Server protocol violation
#define HZERR_TIMEOUT 1067 // Operation timed out
#define HZERR_RELEASE 1068 // Failed to release a resorce
#define HZERR_SHUTDOWN 1069 // Error occured during shutdown
global const hzEcode E_NOSOCKET (HZERR_NOSOCKET) ; // Cannot get a TCP/IP socket
global const hzEcode E_HOSTFAIL (HZERR_HOSTFAIL) ; // Host server offline
global const hzEcode E_HOSTRETRY (HZERR_HOSTRETRY) ; // Host server is up, accepts clients but cuts them off with too busy message
global const hzEcode E_SENDFAIL (HZERR_SENDFAIL) ; // Cannot connect to host, server maybe down
global const hzEcode E_RECVFAIL (HZERR_RECVFAIL) ; // Cannot connect to host, server maybe down
global const hzEcode E_PROTOCOL (HZERR_PROTOCOL) ; // Client/Server protocol violation
global const hzEcode E_TIMEOUT (HZERR_TIMEOUT) ; // Operation timed out
global const hzEcode E_RELEASE (HZERR_RELEASE) ; // Failed to release a resorce
global const hzEcode E_SHUTDOWN (HZERR_SHUTDOWN) ; // Error occured during shutdown
static const char* hzerr_NOSOCKET = "1061 E_NOSOCKET" ;
static const char* hzerr_HOSTFAIL = "1062 E_HOSTFAIL" ;
static const char* hzerr_HOSTRETRY = "1063 E_HOSTRETRY" ;
static const char* hzerr_SENDFAIL = "1064 E_SENDFAIL" ;
static const char* hzerr_RECVFAIL = "1065 E_RECVFAIL" ;
static const char* hzerr_PROTOCOL = "1066 E_PROTOCOL" ;
static const char* hzerr_TIMEOUT = "1067 E_TIMEOUT" ;
static const char* hzerr_RELEASE = "1068 E_RELEASE" ;
static const char* hzerr_SHUTDOWN = "1069 E_SHUTDOWN" ;
/*
** Email errors
*/
#define HZERR_BADSENDER 1071 // No sender email addr
#define HZERR_BADADDRESS 1072 // Badly formed address
#define HZERR_NOACCOUNT 1073 // A Mail server has denied the existence of the account
#define HZERR_SYSERROR 1074 // System command error
global const hzEcode E_BADSENDER (HZERR_BADSENDER) ; // No sender email addr
global const hzEcode E_BADADDRESS (HZERR_BADADDRESS) ; // Badly formed address
global const hzEcode E_NOACCOUNT (HZERR_NOACCOUNT) ; // A Mail server has denied the existence of the account
global const hzEcode E_SYSERROR (HZERR_SYSERROR) ; // System command error
static const char* hzerr_BADSENDER = "1071 E_BADSENDER" ;
static const char* hzerr_BADADDRESS = "1072 E_BADADDRESS" ;
static const char* hzerr_NOACCOUNT = "1073 E_NOACCOUNT" ;
static const char* hzerr_SYSERROR = "1074 E_SYSERROR" ;
/*
** Functions
*/
const char* Err2Txt (hzEcode errCode)
{
// Category: Diagnostics
//
// Converts a hzEcode value to it's text description.
//
// Arguments: 1) errCode The error code
//
// Returns: Pointer (cstr) being description of supplied error code
_hzfunc(__func__) ;
switch (errCode.Value())
{
case HZERR_OK: return hzerr_OK ;
case HZERR_ARGUMENT: return hzerr_ARGUMENT ;
case HZERR_TYPE: return hzerr_TYPE ;
case HZERR_FORMAT: return hzerr_FORMAT ;
case HZERR_RANGE: return hzerr_RANGE ;
case HZERR_BADVALUE: return hzerr_BADVALUE ;
case HZERR_BADCALL: return hzerr_BADCALL ;
case HZERR_INITFAIL: return hzerr_INITFAIL ;
case HZERR_INITDUP: return hzerr_INITDUP ;
case HZERR_NOINIT: return hzerr_NOINIT ;
case HZERR_SETONCE: return hzerr_SETONCE ;
case HZERR_EXCLUDE: return hzerr_EXCLUDE ;
case HZERR_CONFLICT: return hzerr_CONFLICT ;
case HZERR_SEQUENCE: return hzerr_SEQUENCE ;
case HZERR_DUPLICATE: return hzerr_DUPLICATE ;
case HZERR_NODATA: return hzerr_NODATA ;
case HZERR_NOTFOUND: return hzerr_NOTFOUND ;
case HZERR_INSERT: return hzerr_INSERT ;
case HZERR_DELETE: return hzerr_DELETE ;
case HZERR_CORRUPT: return hzerr_CORRUPT ;
case HZERR_PARSE: return hzerr_PARSE ;
case HZERR_SYNTAX: return hzerr_SYNTAX ;
case HZERR_NOCREATE: return hzerr_NOCREATE ;
case HZERR_OPENFAIL: return hzerr_OPENFAIL ;
case HZERR_NOTOPEN: return hzerr_NOTOPEN ;
case HZERR_READFAIL: return hzerr_READFAIL ;
case HZERR_WRITEFAIL: return hzerr_WRITEFAIL ;
case HZERR_MEMORY: return hzerr_MEMORY ;
case HZERR_OVERFLOW: return hzerr_OVERFLOW ;
case HZERR_DNS_NOHOST: return hzerr_DNS_NOHOST ;
case HZERR_DNS_NODATA: return hzerr_DNS_NODATA ;
case HZERR_DNS_RETRY: return hzerr_DNS_RETRY ;
case HZERR_DNS_FAILED: return hzerr_DNS_FAILED ;
case HZERR_NOSOCKET: return hzerr_NOSOCKET ;
case HZERR_HOSTFAIL: return hzerr_HOSTFAIL ;
case HZERR_HOSTRETRY: return hzerr_HOSTRETRY ;
case HZERR_SENDFAIL: return hzerr_SENDFAIL ;
case HZERR_RECVFAIL: return hzerr_RECVFAIL ;
case HZERR_PROTOCOL: return hzerr_PROTOCOL ;
case HZERR_TIMEOUT: return hzerr_TIMEOUT ;
case HZERR_RELEASE: return hzerr_RELEASE ;
case HZERR_SHUTDOWN: return hzerr_SHUTDOWN ;
case HZERR_BADSENDER: return hzerr_BADSENDER ;
case HZERR_BADADDRESS: return hzerr_BADADDRESS ;
case HZERR_NOACCOUNT: return hzerr_NOACCOUNT ;
case HZERR_SYSERROR: return hzerr_SYSERROR ;
}
return 0 ;
}
const char* ShowErrno (void)
{
// Category: Diagnostics
//
// Convert errno to a text string for diagnostic purposes
//
// Arguments: None
//
// Returns: Pointer (cstr) being description of current value of errno as cstr
static const char* _errnos [] =
{
"0 NOERROR: Alles ist in ordnung",
"1 EPERM: Operation not permitted",
"2 ENOENT: No such file or directory",
"3 ESRCH: No such process",
"4 EINTR: Interrupted system call",
"5 EIO: I/O error",
"6 ENXIO: No such device or address",
"7 E2BIG: Argument list too long",
"8 ENOEXEC: Exec format error",
"9 EBADF: Bad file number",
"10 ECHILD: No child processes",
"11 EAGAIN: Try again",
"12 ENOMEM: Out of memory",
"13 EACCES: Permission denied",
"14 EFAULT: Bad address",
"15 ENOTBLK: Block device required",
"16 EBUSY: Device or resource busy",
"17 EEXIST: File exists",
"18 EXDEV: Cross-device link",
"19 ENODEV: No such device",
"20 ENOTDIR: Not a directory",
"21 EISDIR: Is a directory",
"22 EINVAL: Invalid argument",
"23 ENFILE: File table overflow",
"24 EMFILE: Too many open files",
"25 ENOTTY: Not a typewriter",
"26 ETXTBSY: Text file busy",
"27 EFBIG: File too large",
"28 ENOSPC: No space left on device",
"29 ESPIPE: Illegal seek",
"30 EROFS: Read-only file system",
"31 EMLINK: Too many links",
"32 EPIPE: Broken pipe",
"33 EDOM: Math argument out of domain of func",
"34 ERANGE: Math result not representable",
"35 EDEADLK: Resource deadlock would occur",
"36 ENAMETOOLONG: File name too long",
"37 ENOLCK: No record locks available",
"38 ENOSYS: Function not implemented",
"39 ENOTEMPTY: Directory not empty",
"40 ELOOP: Too many symbolic links encountered",
"41 EWOULDBLOCK: (EAGAIN 11) Operation would block",
"42 ENOMSG: No message of desired type",
"43 EIDRM: Identifier removed",
"44 ECHRNG: Channel number out of range",
"45 EL2NSYNC: Level 2 not synchronized",
"46 EL3HLT: Level 3 halted",
"47 EL3RST: Level 3 reset",
"48 ELNRNG: Link number out of range",
"49 EUNATCH: Protocol driver not attached",
"50 ENOCSI: No CSI structure available",
"51 EL2HLT: Level 2 halted",
"52 EBADE: Invalid exchange",
"53 EBADR: Invalid request descriptor",
"54 EXFULL: Exchange full",
"55 ENOANO: No anode",
"56 EBADRQC: Invalid request code",
"57 EBADSLT: Invalid slot",
"58 EDEADLOCK: (EDEADLK 35) Deadlock",
"59 EBFONT: Bad font file format",
"60 ENOSTR: Device not a stream",
"61 ENODATA: No data available",
"62 ETIME: Timer expired",
"63 ENOSR: Out of streams resources",
"64 ENONET: Machine is not on the network",
"65 ENOPKG: Package not installed",
"66 EREMOTE: Object is remote",
"67 ENOLINK: Link has been severed",
"68 EADV: Advertise error",
"69 ESRMNT: Srmount error",
"70 ECOMM: Communication error on send",
"71 EPROTO: Protocol error",
"72 EMULTIHOP: Multihop attempted",
"73 EDOTDOT: RFS specific error",
"74 EBADMSG: Not a data message",
"75 EOVERFLOW: Value too large for defined data type",
"76 ENOTUNIQ: Name not unique on network",
"77 EBADFD: File descriptor in bad state",
"78 EREMCHG: Remote address changed",
"79 ELIBACC: Can not access a needed shared library",
"80 ELIBBAD: Accessing a corrupted shared library",
"81 ELIBSCN: .lib section in a.out corrupted",
"82 ELIBMAX: Attempting to link in too many shared libraries",
"83 ELIBEXEC: Cannot exec a shared library directly",
"84 EILSEQ: Illegal byte sequence",
"85 ERESTART: Interrupted system call should be restarted",
"86 ESTRPIPE: Streams pipe error",
"87 EUSERS: Too many users",
"88 ENOTSOCK: Socket operation on non-socket",
"89 EDESTADDRREQ: Destination address required",
"90 EMSGSIZE: Message too long",
"91 EPROTOTYPE: Protocol wrong type for socket",
"92 ENOPROTOOPT: Protocol not available",
"93 EPROTONOSUPPORT: Protocol not supported",
"94 ESOCKTNOSUPPORT: Socket type not supported",
"95 EOPNOTSUPP: Operation not supported on transport endpoint",
"96 EPFNOSUPPORT: Protocol family not supported",
"97 EAFNOSUPPORT: Address family not supported by protocol",
"98 EADDRINUSE: Address already in use",
"99 EADDRNOTAVAIL: Cannot assign requested address",
"100 ENETDOWN: Network is down",
"101 ENETUNREACH: Network is unreachable",
"102 ENETRESET: Network dropped connection because of reset",
"103 ECONNABORTED: Software caused connection abort",
"104 ECONNRESET: Connection reset by peer",
"105 ENOBUFS: No buffer space available",
"106 EISCONN: Transport endpoint is already connected",
"107 ENOTCONN: Transport endpoint is not connected",
"108 ESHUTDOWN: Cannot send after transport endpoint shutdown",
"109 ETOOMANYREFS: Too many references: cannot splice",
"110 ETIMEDOUT: Connection timed out",
"111 ECONNREFUSED: Connection refused",
"112 EHOSTDOWN: Host is down",
"113 EHOSTUNREACH: No route to host",
"114 EALREADY: Operation already in progress",
"115 EINPROGRESS: Operation now in progress",
"116 ESTALE: Stale NFS file handle",
"117 EUCLEAN: Structure needs cleaning",
"118 ENOTNAM: Not a XENIX named type file",
"119 ENAVAIL: No XENIX semaphores available",
"120 EISNAM: Is a named type file",
"121 EREMOTEIO: Remote I/O error",
"122 EDQUOT: Quota exceeded",
"123 ENOMEDIUM: No medium found",
"124 EMEDIUMTYPE: Wrong medium type",
"125 ECANCELED: Operation Canceled",
"126 ENOKEY: Required key not available",
"127 EKEYEXPIRED: Key has expired",
"128 EKEYREVOKED: Key has been revoked",
"129 EKEYREJECTED: Key was rejected by service",
"130 EOWNERDEAD: Owner died",
"131 ENOTRECOVERABLE: State not recoverable",
"Invalid errno",
""
} ;
if (errno < 0 || errno > 131)
return _errnos[132] ;
else
return _errnos[errno] ;
}
const char* ShowErrorSSL (uint32_t err)
{
// Category: Diagnostics
//
// Convert SSL Errors to a text string for diagnostic purposes
//
// Arguments: 1) err SSL error code
//
// Returns: Pointer (cstr) being description of current value of SSL error
static const char* _err [] =
{
"SSL_ERROR_NONE I/O operation success",
"SSL_ERROR_ZERO_RETURN Closure alert has occured (for clean closure)",
"SSL_ERROR_WANT_READ Read operation incomplete",
"SSL_ERROR_WANT_WRITE Write operation incomplete",
"SSL_ERROR_WANT_CONNECT Connect operation incomplete",
"SSL_ERROR_WANT_ACCEPT Accept operation incomplete",
"SSL_ERROR_WANT_X509_LOOKUP Op did not complete because an app callback has asked to be called again",
"SSL_ERROR_SYSCALL Socket error",
"SSL_ERROR_SSL Library error",
"SSL_ERROR_SSL undefined",
""
} ;
if (err > 9)
return _err[9] ;
else
return _err[err] ;
}
/*
** Error Support Functions
*/
enum hzEaction
{
// HadronZoo Warning/Error action codes. This enum is provided specifically for calling the error reporting functions hzerr(), hzwarn() and hzexit().
HZ_WARNING, // A non critical error, execution may continue without remedial action.
HZ_ERROR, // A critical error, continued execution requires remedial action.
HZ_SHUTDOWN, // A critical error, system must enter shutdown mode and stop accepting new requests.
HZ_FATAL // A critical error, execution will terminate imeadiately.
} ;
static void _makeErrmsg (hzChain& E, hzEaction eAction, hzEcode eError)
{
// Support function to the public HadronZoo error reporting functions hzerr() and hzwarn() and well as the report and exit function hzexit(). Its role is
// simply to build the error report in the supplied chain.
//
// Arguments: 1) E Reference to chain for building error message
// 2) eAction Message action
// 3) eError Error code
//
// Returns: None
hzXDate x ; // System full date
x.SysDateTime() ;
if (eAction == HZ_WARNING) E.Printf("HadronZoo Library Warning\n") ;
else if (eAction == HZ_ERROR) E.Printf("HadronZoo Library Error\n") ;
else if (eAction == HZ_SHUTDOWN) E.Printf("HadronZoo Library Shutdown\n") ;
else if (eAction == HZ_FATAL) E.Printf("HadronZoo Library Controlled Termination\n") ;
else
E.Printf("HadronZoo Library Fatal Error\n") ;
E.Printf("\tTime: %04d/%02d/%02d-%02d:%02d:%02d.%06d\n", x.Year(), x.Month(), x.Day(), x.Hour(), x.Min(), x.Sec(), x.uSec()) ;
E.Printf("\tProcess id: %05d\n", getpid()) ;
E.Printf("\tThread id: %u\n", pthread_self()) ;
E.Printf("\tFunction: %s\n", _hzGlobal_currProc->GetCurrFunc()) ;
E.Printf("\tError: %s\n", Err2Txt(eError)) ;
E.Printf("\tDetails: ") ;
}
/*
** Error and Warning Functions
*/
hzEcode hzwarn (hzEcode eError, const char* va_alist ...)
{
// Gernerate a logfile report and return error code with description supplied as a variable argument
//
// Arguments: 1) eError Error code
// 2) va_alist Variable argument message
//
// Returns: Enum error code as supplied
va_list ap1 ; // Variable arguments list
const char* fmt ; // Format control string
hzChain E ; // Error chain
hzLogger* pLog ; // Output logfile
// Do the args
va_start(ap1, va_alist) ;
fmt = va_alist ;
_makeErrmsg(E, HZ_WARNING, eError) ;
E._vainto(fmt, ap1) ;
va_end(ap1) ;
E.AddByte(CHAR_NL) ;
pLog = GetThreadLogger() ;
if (!pLog)
std::cerr << E ;
else
{
if (pLog->IsOpen())
pLog->Out(E) ;
else
std::cerr << E ;
}
return eError ;
}
hzEcode hzerr (hzEcode eError, const char* va_alist ...)
{
// Report the error for the supplied error code that is assumed to occur within the named function.
//
// Arguments: 1) eError Error code
// 2) va_alist Variable argument message
//
// Returns: Enum error code as supplied
va_list ap1 ; // Variable arguments list
const char* fmt ; // Format control string
hzChain E ; // Error chain
hzLogger* pLog ; // Output logfile
// Do the args
va_start(ap1, va_alist) ;
fmt = va_alist ;
_makeErrmsg(E, HZ_ERROR, eError) ;
E._vainto(fmt, ap1) ;
va_end(ap1) ;
E.AddByte(CHAR_NL) ;
pLog = GetThreadLogger() ;
if (!pLog)
std::cerr << E ;
else
{
if (pLog->IsOpen())
pLog->Out(E) ;
else
std::cerr << E ;
}
return eError ;
}
void hzexit (hzEcode eError, const char* va_alist ...)
{
// Report the error for the supplied error code that is assumed to occur within the named function. Then provide a stack trace for the calling thread and terminate execution
// of the program.
//
// Arguments: 1) eError Error code
// 2) va_alist Error description
//
// Returns: None
va_list ap1 ; // Variable argument list
hzChain E ; // Error chain
hzLogger* pLog ; // Output logfile
hzProcess* phz ; // Process controller
const char* fmt ; // Format control string
phz = GetThreadInfo() ;
_hzGlobal_kill = true ;
_makeErrmsg(E, HZ_FATAL, eError) ;
va_start(ap1, va_alist) ;
fmt = va_alist ;
E._vainto(fmt, ap1) ;
va_end(ap1) ;
E.AddByte(CHAR_NL) ;
pLog = GetThreadLogger() ;
if (!pLog)
std::cerr << E ;
else
{
if (pLog->IsOpen())
pLog->Out(E) ;
else
std::cerr << E ;
}
phz->StackTrace() ;
exit(eError.Value()) ;
}
// FnGrp: Fatal
// Category: Diagnostics
//
// Argument: msg Error description
// Returns: None Exits program
//
// Simplified version of 'hzexit' using just the error description.
//
// Func: Fatal(hzChain&)
// Func: Fatal(const char* ...)
void Fatal (hzChain& error)
{
// Category: Diagnostics
//
// Make a HadronZoo fatal error report using the supplied hzChain (as error message) and place it both in the logfile for the thread and to stderr
//
// Arguments: 1) error The error message as chain
//
// Returns: None
hzChain E ; // Error chain
hzXDate d ; // System full date
hzLogger* pLog ; // Output logfile
hzProcess* phz ; // Process controller
// Get log channel and current date & time
phz = GetThreadInfo() ;
_hzGlobal_kill = true ;
d.SysDateTime() ;
// Populate the errmsg chain
E.Printf("Fatal Error in process %05u (tid %u) at %04d%02d%02d-%02d%02d%02d -> ",
getpid(), pthread_self(), d.Year(), d.Month(), d.Day(), d.Hour(), d.Min(), d.Sec()) ;
E << error ;
// Output the message - deal with case where no logger is found for the current thread or the logger is closed or non-verbose (demon)
pLog = GetThreadLogger() ;
if (!pLog)
std::cerr << E ;
else
{
if (pLog->IsOpen())
pLog->Out(E) ;
else
std::cerr << E ;
}
phz->StackTrace() ;
exit(0) ;
}
void Fatal (const char* va_alist ...)
{
// Category: Diagnostics
//
// Make a HadronZoo fatal error report using varags and place it both in the logfile for the thread and to stderr
//
// Arguments: 1) error The variable argument error message
//
// Returns: None
va_list ap1 ; // Variable argument list
hzChain E ; // Error chain
hzXDate d ; // System full date
hzLogger* pLog ; // Output logfile
hzProcess* phz ; // Process controller
const char* fmt ; // Format control string
// Get log channel and current date & time
//pLog = GetThreadLogger() ;
phz = GetThreadInfo() ;
_hzGlobal_kill = true ;
d.SysDateTime() ;
// Sort the args
va_start(ap1, va_alist) ;
fmt = va_alist ;
// Populate the errmsg chain
E.Printf("Fatal Error in process %05u (tid %u) at %04d%02d%02d-%02d%02d%02d -> ",
getpid(), pthread_self(), d.Year(), d.Month(), d.Day(), d.Hour(), d.Min(), d.Sec()) ;
E._vainto(fmt, ap1) ;
va_end(ap1) ;
// Output the message - deal with case where no logger is found for the current thread or the logger is closed or non-verbose (demon)
pLog = GetThreadLogger() ;
if (!pLog)
std::cerr << E ;
else
{
if (pLog->IsOpen())
pLog->Out(E) ;
else
std::cerr << E ;
}
phz->StackTrace() ;
exit(0) ;
}