Exception vs error code vs assert

I am working on a library that generates device reports. The generate_report (const std::string& no) member function generate_report (const std::string& no) may fail for various reasons:

  • wrong report
  • invalid state ( report_generator - FSM)
  • inactive device
  • error creating report

What error handling mechanism is best suited for these errors?

  • just return true or false
  • return error code
  • assert and log
  • throw exception (s)
  • any combination of the above

Some contextual information: the usual workflow is as follows. The user activates the device, selects a report from the list and clicks “generate”.

EDIT: Thanks for the answers so far! It’s now clear to me when to use statements and when to do error handling. As for error handling, error codes and exceptions have both pros and cons. I think I'm looking for exceptions (and creating four classes for the above errors), but I'm not sure yet. I always thought of exceptions to "unexpected situations." Invalid report no is not unexpected. Any advice? :)

+18
c ++ exception assert error-handling
Sep 07 '09 at 9:00
source share
9 answers

Any of them have different goals:

  • error code vers. Exception (s): exceptions and error codes represent different idioms on how to handle result code curves. Exceptions are more reliable - result codes may be ignored or lost. The library should usually clearly distinguish where / which exceptions are thrown and when error codes are used. At best, use only one of them.

  • return true or false : specialization of error codes. Usually the worst idea is only good if there is nothing more to report than good or bad (i.e. malloc returns either good or bad (= NULL ).

  • assert and log: these are debugging methods and should not be used as reporting mechanisms for users / clients. He claims only to say "something happened that I can not handle - I left."

+12
Sep 07 '09 at 9:18
source share

assert is not the right choice. Use assert when you have an invariant; which should never have happened. Do not do things like assert (), that the argument will never be null if it is an error condition and not an invariant.

If it were me, I would use exceptions in the interface and, if I had to, translate error codes using functions used internally if they do not use exceptions. Just be consistent in this (and don't use assert for this stuff).

+10
Sep 07 '09 at 9:03
source share

Exceptions over true / false and error codes have several important advantages:

  • Exceptions cannot be ignored. If your code throws an exception, the caller needs to catch it to avoid getting an unhandled exception.
  • Exceptions can be handled at a higher level than the immediate caller. If you use error codes, you may find yourself in situations where you must check for errors at all levels of your application and pass them back to the caller.

Accessors are used to express things like preconditions in your code, and we hope to find errors during development. However, you should not rely on statements in your release code, and for performance reasons, statements are usually removed from the release code.

+5
Sep 07 '09 at 9:39
source share

I recommend reading the Boost guide [boost.org] community for exceptions and error handling.

+3
07 Sep '09 at 9:17
source share

It is often important which strategy to choose. I’m talking about what integrates best with your library’s clients. If they adopt an exclusion strategy, use exceptions. If they are used to error codes, stick to them.

+2
Sep 07 '09 at 9:03
source share

How reliable are the devices you are reporting?

I ask, because for a large class of devices, not connected, not turned on, from batteries, busy with something else, etc. etc. are fairly normal conditions.

If so, I would prefer to return a status code (pay attention to the error code) if the device is somehow inaccessible.

If, on the other hand, you think these devices are super reliable and truly exceptional for them to not respond, then exception handling can be a way.

It doesn't really matter that mutch as an “exception” is really just a fancy way of coding “if (x! = 0) {goto error_routine;}, but I personally prefer exception handling to handle exceptions rather than ordinary events like end_of_file.

+2
Sep 07 '09 at 9:30
source share

I am going to go against the grain and offer both error codes and exceptions, but only because you are creating a library. Since you say that you are making a library, I assume that the library will be available for code written by people you do not control. Thus, to make your code friendly for different compilers and, possibly, even languages, is good.

So, I would encode the C ++ exception library and provide header files describing your exception classes. I would also code the C interface, which handles exceptions for the user. Now the user can refer to some interface:

 #ifdef __cplusplus__ void generate_report(const std::string& rep_number, ostream& output); extern "C" #endif int generate_report(const char* rep_number, const char* outputfilename, int* error_code, char* error_text, int max_error_text_len); 

The C implementation calls the C ++ implementation:

 extern "C" int generate_report(const char* rep_number, const char* outputfilename, int* error_code, char* error_text, int max_error_text_len) { ofstream os; try { os.open(outputfilename, IOS_WRITE); generate_report(rep_number, os); os.close(); return TRUE; } catch (base_exception& e) { os.close(); if (error_code) *error_code = e.error_code(); if (error_text) strncpy(error_text, e.str(), max_error_text_len); return FALSE; } } 
+2
Sep 07 '09 at 21:07
source share

First - be consistent!

Secondly:

  • just true / false is not enough. It should be combined with error codes (e.g. false + getLastError).
  • error codes are quick, but create some infrastructure to easily convert them to strings.
  • assert / log: no, you want the application to be able to respond to an error
  • exceptions are slower than error codes, but easier to program using a complex control flow.
  • : only true / false + error codes are combined, for the rest BE CONSISTENT , which means: do not combine.
+1
Sep 07 '09 at 9:04
source share
  • Logging should be used if you do not have access to the terminal for reporting read / read errors.
  • return True / False should be combined with error codes. Example: the function returns True on success, False on error, and sets a variable (global or parameter, your choice) with the corresponding error code / description.
  • Exceptions: in my opinion, it is good to combine them with logging and graceful recovery from errors. If this is not possible, you can also resort to error codes, since exceptions do not provide any additional benefits.
  • assert (): As others have pointed out, it compiles on release builds, so fire is up to you.

2s

+1
Sep 07 '09 at 9:29
source share



All Articles