Throwing exceptions: Node.js vs Gevent-Collection of common programming errors

Here is an exmaple code that shows that when a greenlet throws an uncaught excpetion, the whole process won’t be crashed. The code is here and the output is as following:

Traceback (most recent call last):  
File "/usr/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run  
  result = self._run(*self.args, **self.kwargs)  
File "test_exception_greenlet.py", line 31, in _fail  
  raise Exception('you fail')  
Exception: you fail  
 failed with Exception  

win ready? True    
fail ready? True  
win successful()? True  
fail successful()? False  
exception: Exception('you fail',)  

When using gevent to implemenet concurrency tasks, you should generate some coroutines, namely greenlets, and then the main thread should switch to a special greenlet named hub and then the loop happens among greenlets. The workflow is like this:

main thread -> one greenlet -> hub greenlet -> a greenlet -> hub greenlet -> a greenlet -> … -> some greenlet -> main thread -> … (maybe enters the loop again)

From here, you should know how a greenlet runs internally. A greenlet is an instance of Greenlet. When a greenlet runs, it invokes its run() method. Here is the source code of run() in Greenlet class:

def run(self):
    try:
        if self._start_event is None:
            self._start_event = _dummy_event
        else:
            self._start_event.stop()
        try:
            result = self._run(*self.args, **self.kwargs)
        except:
            self._report_error(sys.exc_info())
            return
        self._report_result(result)
    finally:
        self.__dict__.pop('_run', None)
        self.__dict__.pop('args', None)
        self.__dict__.pop('kwargs', None)

The _run() method here is a binding with a task you want to run as a greenlet. From here you could see that if an exception happens, it will be caught and reported by _report_error() method. By reading the source code of _report_error() and _report_result() which is invoked by the former, you know that it catches the exception and just the greenlet dies but not the whole process. When a greenlet raises an uncaught exception, it dies and the hub greenlet won’t schedule it any more.

If you’re insterested in the implementation of Greenlet, here is the source code

Originally posted 2013-12-25 10:55:19.