6. `ZOOM::exception` and subclasses
Prev | Chapter 3. ZOOM-C++ | Next

## 6. `ZOOM::exception` and subclasses

The `ZOOM::exception` class is a virtual base class, representing a diagnostic generated by the ZOOM-C++ library or returned from a server. Its subclasses represent particular kinds of error.

When any of the ZOOM methods fail, they respond by `throw`ing an object of type `exception` or one of its subclasses. This most usually happens with the `connection` constructor, the various query constructors, the `resultSet` constructor (which is actually the searching method) and `resultSet::getRecord()`.

The base class has this declaration:

        class exception {
        public:
          exception (int code);
          int errcode () const;
          const char *errmsg () const;
        };

It has three concrete subclasses:

### 6.1. `ZOOM::systemException`

        class systemException: public exception {
        public:
          systemException ();
          int errcode () const;
          const char *errmsg () const;
        };

Represents a ``system error'', typically indicating that a system call failed - often in the low-level networking code that underlies Z39.50. `errcode()` returns the value that the system variable `errno` had at the time the exception was constructed; and `errmsg()` returns a human-readable error-message corresponidng to that error code.

### 6.2. `ZOOM::bib1Exception`

        class bib1Exception: public exception {
        public:
          bib1Exception (int errcode, const char *addinfo);
          int errcode () const;
          const char *errmsg () const;
          const char *addinfo () const;
        };

Represents an error condition communicated by a Z39.50 server. `errcode()` returns the BIB-1 diagnostic code of the error, and `errmsg()` a human-readable error message corresponding to that code. `addinfo()` returns any additional information associated with the error.

For example, if a ZOOM application tries to search in the ``Voyager'' database of a server that does not have a database of that name, a `bib1Exception` will be thrown in which `errcode()` returns 109, `errmsg()` returns the corresponding error message ``Database unavailable'' and `addinfo()` returns the name of the requested, but unavailable, database.

### 6.3. `ZOOM::queryException`

        class queryException: public exception {
        public:
          static const int PREFIX = 1;
          static const int CCL = 2;
          queryException (int qtype, const char *source);
          int errcode () const;
          const char *errmsg () const;
          const char *addinfo () const;
        };

This class represents an error in parsing a query into a form that a Z39.50 can understand. It must be created with the `qtype` parameter equal to one of the query-type constants, which can be retrieved via the `errcode()` method; `errmsg()` returns an error-message specifying which kind of query was malformed; and `addinfo()` returns a copy of the query itself (that is, the value of `source` with which the exception object was created.)

### 6.4. Revised Sample Program

Now we can revise the sample program from the introduction to catch exceptions and report any errors:

        /* g++ -o zoom-c++-hw zoom-c++-hw.cpp -lzoompp -lyaz */

        #include <iostream>
        #include <yazpp/zoom.h>

        using namespace ZOOM;

        int main(int argc, char **argv)
        {
            try {
                connection conn("z3950.loc.gov", 7090);
                conn.option("databaseName", "Voyager");
                conn.option("preferredRecordSyntax", "USMARC");
                resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
                const record *rec = rs.getRecord(0);
                cout << rec->render() << endl;
            } catch (systemException &e) {
                cerr << "System error " <<
                    e.errcode() << " (" << e.errmsg() << ")" << endl;
            } catch (bib1Exception &e) {
                cerr << "BIB-1 error " <<
                    e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
            } catch (queryException &e) {
                cerr << "Query error " <<
                    e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
            } catch (exception &e) {
                cerr << "Error " <<
                    e.errcode() << " (" << e.errmsg() << ")" << endl;
            }
        }

The heart of this program is the same as in the original version, but it's now wrapped in a `try` block followed by several `catch` blocks which try to give helpful diagnostics if something goes wrong.

The first such block diagnoses system-level errors such as memory exhaustion or a network connection being broken by a server's untimely death; the second catches errors at the Z39.50 level, such as a server's report that it can't provide records in USMARC syntax; the third is there in case there's something wrong with the syntax of the query (although in this case it's correct); and finally, the last `catch` block is a belt-and-braces measure to be sure that nothing escapes us.

### 6.5. References

- Section 3.7 (Exception) of the ZOOM Abstract API

- Bib-1 Diagnostics on the Z39.50 Maintenance Agency site.

Because C does not support exceptions, ZOOM-C has no API element that corresponds directly with ZOOM-C++'s `exception` class and its subclasses. The closest thing is the `ZOOM_connection_error` function described in The Connections section of the documentation.

Prev | Up | Next
5. `ZOOM::record` | Home | Chapter 4. YAZ C++ API