合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### 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.