surfly/gevent — pull request #450 by rodolfo3 (2014-06-03 15:16:05+00:00)
Title: Keep traceback when a greenlet raise an Exception

Using exc_info to raise the exception, the stack trace are preserved. This allows apps like Sentry keep the data from the original request.

This can be tested with this code:
```
def a():
b()

def b():
c()

def c():
raise Exception("oops")

import gevent
g = gevent.spawn(a)

gevent.joinall([g], raise_error=True)
```

Before this change, the stack trace are like:
```
Traceback (most recent call last):
File "/home/rodolfo/.virtualenvs/learn/local/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
result = self._run(*self.args, **self.kwargs)
File "", line 2, in a
b()
File "", line 2, in b
c()
File "", line 2, in c
raise Exception("oops")
Exception: oops
failed with Exception

---------------------------------------------------------------------------
Exception Traceback (most recent call last)
in ()
----> 1 gevent.joinall([g], raise_error=True)

/home/rodolfo/.virtualenvs/learn/local/lib/python2.7/site-packages/gevent/greenlet.pyc in joinall(greenlets, timeout, raise_error, count)
402 for obj in iwait(greenlets, timeout=timeout):
403 if getattr(obj, 'exception', None) is not None:
--> 404 raise obj.exception
405 if count is not None:
406 count -= 1

Exception: oops
```

After this, we get the original stack:
```
Traceback (most recent call last):
File "/home/rodolfo/.virtualenvs/learn/local/lib/python2.7/site-packages/gevent/greenlet.py", line 328, in run
result = self._run(*self.args, **self.kwargs)
File "", line 2, in a
b()
File "", line 2, in b
c()
File "", line 2, in c
raise Exception("oops")
Exception: oops
failed with Exception

---------------------------------------------------------------------------
Exception Traceback (most recent call last)
in ()
----> 1 gevent.joinall([g], raise_error=True)

/home/rodolfo/.virtualenvs/learn/local/lib/python2.7/site-packages/gevent/greenlet.py in run(self)
326 self._start_event.stop()
327 try:
--> 328 result = self._run(*self.args, **self.kwargs)
329 except:
330 self._report_error(sys.exc_info())

in a()
1 def a():
----> 2 b()
3

in b()
1 def b():
----> 2 c()
3

in c()
1 def c():
----> 2 raise Exception("oops")
3

Exception: oops
```