error.h
// -*- mode: cpp; mode: fold -*-
// SPDX-License-Identifier: GPL-2.0+
// Description /*{{{*/
/* ######################################################################
Global Error Class - Global error mechanism
This class has a single global instance. When a function needs to
generate an error condition, such as a read error, it calls a member
in this class to add the error to a stack of errors.
By using a stack the problem with a scheme like errno is removed and
it allows a very detailed account of what went wrong to be transmitted
to the UI for display. (Errno has problems because each function sets
errno to 0 if it didn't have an error thus eraseing erno in the process
of cleanup)
Several predefined error generators are provided to handle common
things like errno. The general idea is that all methods return a bool.
If the bool is true then things are OK, if it is false then things
should start being undone and the stack should unwind under program
control.
A Warning should not force the return of false. Things did not fail, but
they might have had unexpected problems. Errors are stored in a FIFO
so Pop will return the first item..
I have some thoughts about extending this into a more general UI<->
Engine interface, ie allowing the Engine to say 'The disk is full' in
a dialog that says 'Panic' and 'Retry'.. The error generator functions
like errno, Warning and Error return false always so this is normal:
if (open(..))
return _error->Errno(..);
This file had this historic note, but now includes further changes
under the GPL-2.0+:
This source is placed in the Public Domain, do with it what you will
It was originally written by Jason Gunthorpe.
##################################################################### */
/*}}}*/
#ifndef PKGLIB_ERROR_H
#define PKGLIB_ERROR_H
#include <apt-pkg/macros.h>
#include <iostream>
#include <list>
#include <string>
#include <cstdarg>
#include <cstddef>
class APT_PUBLIC GlobalError /*{{{*/
{
public: /*{{{*/
enum MsgType {
FATAL = 40,
ERROR = 30,
WARNING = 20,
NOTICE = 10,
AUDIT = 5,
DEBUG = 0
};
bool FatalE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool Errno(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool WarningE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool NoticeE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool AuditE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool DebugE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD;
bool InsertErrno(MsgType const &type, const char* Function,
const char* Description,...) APT_PRINTF(4) APT_COLD;
bool InsertErrno(MsgType type, const char* Function,
const char* Description, va_list &args,
int const errsv, size_t &msgSize) APT_COLD;
bool Fatal(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Error(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Warning(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Notice(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Audit(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Debug(const char *Description,...) APT_PRINTF(2) APT_COLD;
bool Insert(MsgType const &type, const char* Description,...) APT_PRINTF(3) APT_COLD;
bool Insert(MsgType type, const char* Description,
va_list &args, size_t &msgSize) APT_COLD;
inline bool PendingError() const APT_PURE {return PendingFlag;};
bool empty(MsgType const &threshold = WARNING) const APT_PURE;
bool PopMessage(std::string &Text);
void Discard();
void DumpErrors(std::ostream &out, MsgType const &threshold = WARNING,
bool const &mergeStack = true);
void inline DumpErrors(MsgType const &threshold) {
DumpErrors(std::cerr, threshold);
}
// mvo: we do this instead of using a default parameter in the
// previous declaration to avoid a (subtle) API break for
// e.g. sigc++ and mem_fun0
void inline DumpErrors() {
DumpErrors(WARNING);
}
void PushToStack();
void RevertToStack();
void MergeWithStack();
size_t StackCount() const APT_PURE {
return Stacks.size();
}
GlobalError();
/*}}}*/
private: /*{{{*/
struct Item {
std::string Text;
MsgType Type;
Item(char const *Text, MsgType const &Type) :
Text(Text), Type(Type) {};
APT_HIDDEN friend std::ostream &operator<<(std::ostream &out, Item i);
};
APT_HIDDEN friend std::ostream &operator<<(std::ostream &out, Item i);
std::list<Item> Messages;
bool PendingFlag;
struct MsgStack {
std::list<Item> Messages;
bool const PendingFlag;
MsgStack(std::list<Item> const &Messages, bool const &Pending) :
Messages(Messages), PendingFlag(Pending) {};
};
std::list<MsgStack> Stacks;
/*}}}*/
};
/*}}}*/
// The 'extra-ansi' syntax is used to help with collisions.
APT_PUBLIC GlobalError *_GetErrorObj();
static struct {
inline GlobalError* operator ->() { return _GetErrorObj(); }
} _error [[maybe_unused]];
#endif
GlobalError
Definition error.h:56
GlobalError::PendingError
bool PendingError() const APT_PURE
is an error in the list?
Definition error.h:254
GlobalError::MsgType
MsgType
a message can have one of following severity
Definition error.h:59
GlobalError::DEBUG
@ DEBUG
for developers only in areas it is hard to print something directly
Definition error.h:72
GlobalError::AUDIT
@ AUDIT
future deprecation warnings, divergence from best practices
Definition error.h:70
GlobalError::ERROR
@ ERROR
An error does hinder the correct execution and should be corrected.
Definition error.h:64
GlobalError::FATAL
@ FATAL
Message will be printed instantly as it is likely that this error will lead to a complete crash.
Definition error.h:62
GlobalError::WARNING
@ WARNING
indicates problem that can lead to errors later on
Definition error.h:66
GlobalError::NOTICE
@ NOTICE
deprecation warnings, old fallback behavior, …
Definition error.h:68
GlobalError::StackCount
size_t StackCount() const APT_PURE
return the deep of the stack
Definition error.h:331
GlobalError::DumpErrors
void DumpErrors(std::ostream &out, MsgType const &threshold=WARNING, bool const &mergeStack=true)
outputs the list of messages to the given stream
Definition error.cc:194
GlobalError::AuditE
bool AuditE(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add an audit message with errno to the list
GlobalError::Insert
bool Insert(MsgType const &type, const char *Description,...) APT_PRINTF(3) APT_COLD
adds an error message with the given type
Definition error.cc:130
GlobalError::Fatal
bool Fatal(const char *Description,...) APT_PRINTF(2) APT_COLD
add an fatal error message to the list
GlobalError::DumpErrors
void DumpErrors()
dumps the messages of type WARNING or higher to std::cerr
Definition error.h:309
GlobalError::Notice
bool Notice(const char *Description,...) APT_PRINTF(2) APT_COLD
add a notice message to the list
GlobalError::DumpErrors
void DumpErrors(MsgType const &threshold)
dumps the list of messages to std::cerr
Definition error.h:297
GlobalError::DebugE
bool DebugE(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add a debug message with errno to the list
GlobalError::Error
bool Error(const char *Description,...) APT_PRINTF(2) APT_COLD
add an Error message to the list
GlobalError::WarningE
bool WarningE(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add a warning message with errno to the list
GlobalError::FatalE
bool FatalE(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add a fatal error message with errno to the list
GlobalError::Audit
bool Audit(const char *Description,...) APT_PRINTF(2) APT_COLD
add an audit message to the list
GlobalError::Warning
bool Warning(const char *Description,...) APT_PRINTF(2) APT_COLD
add a warning message to the list
GlobalError::InsertErrno
bool InsertErrno(MsgType const &type, const char *Function, const char *Description,...) APT_PRINTF(4) APT_COLD
adds an errno message with the given type
Definition error.cc:74
GlobalError::Debug
bool Debug(const char *Description,...) APT_PRINTF(2) APT_COLD
add a debug message to the list
GlobalError::NoticeE
bool NoticeE(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add a notice message with errno to the list
GlobalError::Errno
bool Errno(const char *Function, const char *Description,...) APT_PRINTF(3) APT_COLD
add an Error message with errno to the list