From BlenderWiki

Jump to: navigation, search

Reporting Errors, Warnings and Debug Info

Reporting errors is something that is common to much code in Blender. Currently this is often either done through an blocking error() call which will display a popup menu immediately, or a printf() to the console which can go unnoticed. In 2.5 there are restrictions on when drawing and event handling is allowed, and as such error() calls are not allowed anymore in modules such as blenkernel. As a replacement a ReportList can now be passed along which can gather such error reports and either display them, print them in a console, or return them as an exception to python.

Header

/* Reporting Information and Errors */
 
typedef enum ReportType {
    RPT_DEBUG                   = 0,
    RPT_INFO                    = 1000,
    RPT_WARNING                 = 2000,
    RPT_ERROR                   = 3000,
    RPT_ERROR_INVALID_INPUT     = 3001,
    RPT_ERROR_INVALID_CONTEXT   = 3002,
    RPT_ERROR_OUT_OF_MEMORY     = 3003
} ReportType;
 
enum ReportListFlags {
    RPT_PRINT = 1,
    RPT_STORE = 2
};
 
typedef struct Report {
    struct Report *next, *prev;
    ReportType type;
    char *typestr;
    char *message;
} Report;
 
typedef struct ReportList {
    ListBase list;
    ReportType level;
    int flags;
} ReportList;
 
void BKE_report_list_init(ReportList *reports, int flag);
void BKE_report_list_clear(ReportList *reports);
 
void BKE_report(ReportList *reports, ReportType type, const char *message);
void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...);
 
ReportType BKE_report_level(ReportList *reports);
void BKE_report_level_set(ReportList *reports, ReportType level);
 
int BKE_report_has_error(ReportList *reports);

Report Types

There are four levels of reports: debug information, information for the user, warnings and errors. Debug information is only useful to developers and would be printed when running Blender with the -d option. Information for users is information useful to the user but not critical, for example how many vertices were removed in remove doubles or how much memory was used by rendering-- this should not cause a popup menu to be displayed but can be printed to a console. Warnings are information that something may not have gone as expected by the user. Errors mean that something critical has gone wrong, and the operation that was being executed failed in some important way.

For each level there are also more specific types then, for example an out of memory error may be reported rather than an undefined error.

Report Lists and Context

ReportLists's can be passed along to various pieces of code. For example file reading and writing function can take such a list as an argument and then gather warnings and errors. Or modifiers could also report errors in such a list which then could be displayed in the modifier stack. The context has a report list currently; however, it may be better to give operators such a report list rather than context. Which approach is more convenient and clear needs to be figured out.

When python code calls an operator or other code, it should be able to pass along its own ReportList to gather errors and throw an exception if one is found.

User Interface

How such reports are best displayed in the user interface is debatable, as blocking popups, non-blocking messages prominently displayed, or in a console, etc. This document just tries to define a few different levels of reports that should be flexible enough to make different kinds of user interface ideas for such interaction work.