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
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
block all other requests from processing.
"""
x = 0
while True:
x += 1
for x in range(10):
time.sleep(1)
yield f"{x}\r\n"
@ -44,9 +42,7 @@ def threaded_counter():
time.sleep(1)
return f"{x}\r\n"
x = 0
while True:
x += 1
for x in range(10):
yield deferToThread(delayed_callback, x)
@ -65,9 +61,7 @@ def deferred_counter():
def delayed_callback(x):
return f"{x}\r\n"
x = 0
while True:
x += 1
for x in range(10):
yield deferLater(reactor, 1, delayed_callback, x)

View File

@ -6,7 +6,7 @@ import typing
import urllib.parse
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.protocols.basic import LineOnlyReceiver
@ -100,18 +100,22 @@ class GeminiProtocol(LineOnlyReceiver):
try:
environ = self.build_environ()
response_generator = await maybeDeferred(
self.app, environ, self.write_status
)
# Yield control of the event loop
await deferLater(self.server.reactor, 0)
while True:
data = await maybeDeferred(response_generator.__next__)
if data is None:
break
self.write_body(data)
response_generator = self.app(environ, self.write_status)
if isinstance(response_generator, Deferred):
response_generator = await response_generator
else:
# Yield control of the event loop
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:
self.server.log_message(traceback.format_exc())
self.write_status(Status.CGI_ERROR, "An unexpected error occurred")