Better error handling

This commit is contained in:
Michael Lazar 2020-05-26 10:22:49 -04:00
parent ec63a0bc9d
commit 6d84442992
2 changed files with 19 additions and 21 deletions

View File

@ -1,5 +1,5 @@
""" """
An endpoint that streams incrementing numbers forever. An endpoint that streams numbers counting to 10.
This is an example of how a jetforce application can respond with a generator This is an example of how a jetforce application can respond with a generator
function instead of plain text/bytes. The server will iterate over the function instead of plain text/bytes. The server will iterate over the
@ -22,9 +22,7 @@ def blocking_counter():
The calls to time.sleep(1) will run in the main twisted event loop and The calls to time.sleep(1) will run in the main twisted event loop and
block all other requests from processing. block all other requests from processing.
""" """
x = 0 for x in range(10):
while True:
x += 1
time.sleep(1) time.sleep(1)
yield f"{x}\r\n" yield f"{x}\r\n"
@ -44,9 +42,7 @@ def threaded_counter():
time.sleep(1) time.sleep(1)
return f"{x}\r\n" return f"{x}\r\n"
x = 0 for x in range(10):
while True:
x += 1
yield deferToThread(delayed_callback, x) yield deferToThread(delayed_callback, x)
@ -65,9 +61,7 @@ def deferred_counter():
def delayed_callback(x): def delayed_callback(x):
return f"{x}\r\n" return f"{x}\r\n"
x = 0 for x in range(10):
while True:
x += 1
yield deferLater(reactor, 1, delayed_callback, x) yield deferLater(reactor, 1, delayed_callback, x)

View File

@ -6,7 +6,7 @@ import typing
import urllib.parse import urllib.parse
from twisted.internet.address import IPv4Address, IPv6Address from twisted.internet.address import IPv4Address, IPv6Address
from twisted.internet.defer import ensureDeferred, maybeDeferred from twisted.internet.defer import Deferred, ensureDeferred
from twisted.internet.task import deferLater from twisted.internet.task import deferLater
from twisted.protocols.basic import LineOnlyReceiver from twisted.protocols.basic import LineOnlyReceiver
@ -100,18 +100,22 @@ class GeminiProtocol(LineOnlyReceiver):
try: try:
environ = self.build_environ() environ = self.build_environ()
response_generator = await maybeDeferred( response_generator = self.app(environ, self.write_status)
self.app, environ, self.write_status if isinstance(response_generator, Deferred):
) response_generator = await response_generator
# Yield control of the event loop else:
await deferLater(self.server.reactor, 0)
while True:
data = await maybeDeferred(response_generator.__next__)
if data is None:
break
self.write_body(data)
# Yield control of the event loop # Yield control of the event loop
await deferLater(self.server.reactor, 0) await deferLater(self.server.reactor, 0)
for data in response_generator:
if isinstance(data, Deferred):
data = await data
self.write_body(data)
else:
self.write_body(data)
# Yield control of the event loop
await deferLater(self.server.reactor, 0)
except Exception: except Exception:
self.server.log_message(traceback.format_exc()) self.server.log_message(traceback.format_exc())
self.write_status(Status.CGI_ERROR, "An unexpected error occurred") self.write_status(Status.CGI_ERROR, "An unexpected error occurred")