views:

122

answers:

2

Is there a common pattern for propagating details of both errors and warnings? By errors I mean serious problems that should cause the flow of code to stop. By warnings I mean issues that merit informing the user of a problem, but are too trivial to stop program flow.

I currently use exceptions to deal with hard errors, and the Python logging framework to record warnings. But now I want to record warnings in a database field of the record currently being processed instead. I guess, I want the warnings to bubble up in the same manner as exceptions, but without stopping program flow.

>>> import logging
>>>
>>> def process_item(item):
...     if item:
...         if item == 'broken':
...             logging.warning('soft error, continue with next item')

...     else:
...         raise Exception('hard error, cannot continue')
...
>>> process_item('good')
>>> process_item(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in process_item
Exception: hard error, cannot continue
>>> process_item('broken')
WARNING:root:soft error, continue with next item

This example (and my current problem) is in Python, but it should apply to other languages with exceptions too.


Following David's suggestion and a brief play with the example below, Python's warnings module is the way to go.

import warnings

class MyWarning(Warning):
    pass

def causes_warnings():
    print 'enter causes_warnings'
    warnings.warn("my warning", MyWarning)
    print 'leave causes_warnings'

def do_stuff():
    print 'enter do_stuff'
    causes_warnings()
    causes_warnings()
    causes_warnings()
    print 'leave do_stuff'

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a number of warnings.
    do_stuff()
    # Do something (not very) useful with the warnings generated
    print 'Warnings:',','.join([str(warning.message) for warning in w])

Output:

enter do_stuff
enter causes_warnings
leave causes_warnings
enter causes_warnings
leave causes_warnings
enter causes_warnings
leave causes_warnings
leave do_stuff
Warnings: my warning,my warning,my warning

Note: Python 2.6+ is required for catch_warnings.

A: 

Serious errors should bubble up, warning should just be logged in place without throwing exceptions.

Chris Ballance
+5  A: 

Look into Python's warnings module, http://docs.python.org/library/warnings.html

I don't think there's much you can say about this problem without specifying the language, as non-terminal error handling varies greatly from one language to another.

David Zaslavsky
+1: warnings module. Icky to configure the first time (soooo many options) but once configured it rules.
S.Lott
Crossbreeding warnings and logging modules is not easy but it is possible with some work.
J.F. Sebastian