6.2 Throwing exceptions

Most client code need never worry about anything more than catching exceptions thrown by the core. If you are implementing your own devices or extending the core of MuPDF, then you will need to know how to generate (and pass on) your own exceptions.

An exception is constructed and thrown from an integer code and a printf like string:

enum 
{ 
   FZ_ERROR_NONE = 0, 
   FZ_ERROR_MEMORY = 1, 
   FZ_ERROR_GENERIC = 2, 
   FZ_ERROR_SYNTAX = 3, 
   FZ_ERROR_TRYLATER = 4, 
   FZ_ERROR_ABORT = 5, 
   FZ_ERROR_COUNT 
}; 
 
void fz_throw(fz_context *ctx, int errcode, const char *, ...);

In almost all cases, you should be using FZ_ERROR_GENERIC, for example:

fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to open file ’%s", filename);

FZ_ERROR_MEMORY is reserved for exceptions thrown due to a memory allocation failing. This will rarely be thrown by application code; the typical generators of such exceptions are fz_malloc/fz_calloc/fz_realloc etc.

FZ_ERROR_SYNTAX is reserved for exceptions thrown during interpretation of document files due to syntax errors. This enables the interpreter code to keep track of how many syntax errors have been found in a file, and to abort interpretation after a reasonable number have been passed.

FZ_ERROR_TRYLATER is reserved for exceptions thrown due to lack of data in progressive mode (see chapter 16 Progressive Mode for more details). Catching an error of this type can trigger different handling, whereby the operation is retried when more data has arrived.

FZ_ERROR_ABORT is reserved for exceptions that should stop any ongoing operations; for instance, while looping over the annotations on a page to render them, most exceptions are caught at the top level and ignored, ensuring that a single broken annotation doesn’t cause subsequent annotations to be skipped. FZ_ERROR_ABORT can be used to override this behaviour and cause the annotation rendering process to end as swiftly as possible.