### Navigation
- [index](# "General Index")
- [modules](# "Python Module Index") |
- [next](# "tornado.testing — Unit testing support for asynchronous code") |
- [previous](# "tornado.options — Command-line parsing") |
- [Tornado 4.4.dev1 documentation](#) »
- [Utilities](#) »
# `tornado.stack_context` — Exception handling across asynchronous callbacks
[`StackContext`](# "tornado.stack_context.StackContext") allows applications to maintain threadlocal-like statethat follows execution as it moves to other execution contexts.
The motivating examples are to eliminate the need for explicit`async_callback` wrappers (as in [`tornado.web.RequestHandler`](# "tornado.web.RequestHandler")), and toallow some additional context to be kept for logging.
This is slightly magic, but it's an extension of the idea that anexception handler is a kind of stack-local state and when that stackis suspended and resumed in a new context that state needs to bepreserved. [`StackContext`](# "tornado.stack_context.StackContext") shifts the burden of restoring that statefrom each call site (e.g. wrapping each [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") callbackin `async_callback`) to the mechanisms that transfer control fromone context to another (e.g. [`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient") itself, [`IOLoop`](# "tornado.ioloop.IOLoop"),thread pools, etc).
Example usage:
~~~
@contextlib.contextmanager
def die_on_error():
try:
yield
except Exception:
logging.error("exception in asynchronous operation",exc_info=True)
sys.exit(1)
with StackContext(die_on_error):
# Any exception thrown here *or in callback and its descendants*
# will cause the process to exit instead of spinning endlessly
# in the ioloop.
http_client.fetch(url, callback)
ioloop.start()
~~~
Most applications shouldn't have to work with [`StackContext`](# "tornado.stack_context.StackContext") directly.Here are a few rules of thumb for when it's necessary:
- If you're writing an asynchronous library that doesn't rely on astack_context-aware library like [`tornado.ioloop`](# "tornado.ioloop") or [`tornado.iostream`](# "tornado.iostream")(for example, if you're writing a thread pool), use[`stack_context.wrap()`](# "tornado.stack_context.wrap") before any asynchronous operations to capture thestack context from where the operation was started.
- If you're writing an asynchronous library that has some sharedresources (such as a connection pool), create those shared resourceswithin a `with stack_context.NullContext():` block. This will prevent`StackContexts` from leaking from one request to another.
- If you want to write something like an exception handler that willpersist across asynchronous calls, create a new [`StackContext`](# "tornado.stack_context.StackContext") (or[`ExceptionStackContext`](# "tornado.stack_context.ExceptionStackContext")), and make your asynchronous calls in a `with`block that references your [`StackContext`](# "tornado.stack_context.StackContext").
*class *`tornado.stack_context.``StackContext`(*context_factory*)[[source]](#)
Establishes the given context as a StackContext that will be transferred.
Note that the parameter is a callable that returns a contextmanager, not the context itself. That is, where for anon-transferable context manager you would say:
~~~
with my_context():
~~~
StackContext takes the function itself rather than its result:
~~~
with StackContext(my_context):
~~~
The result of `with StackContext() as cb:` is a deactivationcallback. Run this callback when the StackContext is no longerneeded to ensure that it is not propagated any further (note thatdeactivating a context does not affect any instances of thatcontext that are currently pending). This is an advanced featureand not necessary in most applications.
*class *`tornado.stack_context.``ExceptionStackContext`(*exception_handler*)[[source]](#)
Specialization of StackContext for exception handling.
The supplied `exception_handler` function will be called in theevent of an uncaught exception in this context. The semantics aresimilar to a try/finally clause, and intended use cases are to logan error, close a socket, or similar cleanup actions. The`exc_info` triple `(type, value, traceback)` will be passed to theexception_handler function.
If the exception handler returns true, the exception will beconsumed and will not be propagated to other exception handlers.
*class *`tornado.stack_context.``NullContext`[[source]](#)
Resets the [`StackContext`](# "tornado.stack_context.StackContext").
Useful when creating a shared resource on demand (e.g. an[`AsyncHTTPClient`](# "tornado.httpclient.AsyncHTTPClient")) where the stack that caused the creating isnot relevant to future operations.
`tornado.stack_context.``wrap`(*fn*)[[source]](#)
Returns a callable object that will restore the current [`StackContext`](# "tornado.stack_context.StackContext")when executed.
Use this whenever saving a callback to be executed later in adifferent execution context (either in a different thread orasynchronously in the same thread).
`tornado.stack_context.``run_with_stack_context`(*context*, *func*)[[source]](#)
Run a coroutine `func` in the given [`StackContext`](# "tornado.stack_context.StackContext").
It is not safe to have a `yield` statement within a `with StackContext`block, so it is difficult to use stack context with [`gen.coroutine`](# "tornado.gen.coroutine").This helper function runs the function in the correct context whilekeeping the `yield` and `with` statements syntactically separate.
Example:
~~~
@gen.coroutine
def incorrect():
with StackContext(ctx):
# ERROR: this will raise StackContextInconsistentError
yield other_coroutine()
@gen.coroutine
def correct():
yield run_with_stack_context(StackContext(ctx), other_coroutine)
~~~
New in version 3.1.
© Copyright 2009-2016, The Tornado Authors. Created using [Sphinx](http://sphinx-doc.org/) 1.3.5.
- User's guide
- Introduction
- Asynchronous and non-Blocking I/O
- Coroutines
- Queue example - a concurrent web spider
- Structure of a Tornado web application
- Templates and UI
- Authentication and security
- Running and deploying
- Web framework
- tornado.web — RequestHandler and Application classes
- tornado.template — Flexible output generation
- tornado.escape — Escaping and string manipulation
- tornado.locale — Internationalization support
- tornado.websocket — Bidirectional communication to the browser
- HTTP servers and clients
- tornado.httpserver — Non-blocking HTTP server
- tornado.httpclient — Asynchronous HTTP client
- tornado.httputil — Manipulate HTTP headers and URLs
- tornado.http1connection – HTTP/1.x client/server implementation
- Asynchronous networking
- tornado.ioloop — Main event loop
- tornado.iostream — Convenient wrappers for non-blocking sockets
- tornado.netutil — Miscellaneous network utilities
- tornado.tcpclient — IOStream connection factory
- tornado.tcpserver — Basic IOStream-based TCP server
- Coroutines and concurrency
- tornado.gen — Simplify asynchronous code
- tornado.concurrent — Work with threads and futures
- tornado.locks – Synchronization primitives
- tornado.queues – Queues for coroutines
- tornado.process — Utilities for multiple processes
- Integration with other services
- tornado.auth — Third-party login with OpenID and OAuth
- tornado.wsgi — Interoperability with other Python frameworks and servers
- tornado.platform.asyncio — Bridge between asyncio and Tornado
- tornado.platform.caresresolver — Asynchronous DNS Resolver using C-Ares
- tornado.platform.twisted — Bridges between Twisted and Tornado
- Utilities
- tornado.autoreload — Automatically detect code changes in development
- tornado.log — Logging support
- tornado.options — Command-line parsing
- tornado.stack_context — Exception handling across asynchronous callbacks
- tornado.testing — Unit testing support for asynchronous code
- tornado.util — General-purpose utilities
- Frequently Asked Questions
- Release notes
- What's new in Tornado 4.3
- What's new in Tornado 4.2.1
- What's new in Tornado 4.2
- What's new in Tornado 4.1
- What's new in Tornado 4.0.2
- What's new in Tornado 4.0.1
- What's new in Tornado 4.0
- What's new in Tornado 3.2.2
- What's new in Tornado 3.2.1
- What's new in Tornado 3.2
- What's new in Tornado 3.1.1
- What's new in Tornado 3.1
- What's new in Tornado 3.0.2
- What's new in Tornado 3.0.1
- What's new in Tornado 3.0
- What's new in Tornado 2.4.1
- What's new in Tornado 2.4
- What's new in Tornado 2.3
- What's new in Tornado 2.2.1
- What's new in Tornado 2.2
- What's new in Tornado 2.1.1
- What's new in Tornado 2.1
- What's new in Tornado 2.0
- What's new in Tornado 1.2.1
- What's new in Tornado 1.2
- What's new in Tornado 1.1.1
- What's new in Tornado 1.1
- What's new in Tornado 1.0.1
- What's new in Tornado 1.0