Skip to content

Commit 01fe45f

Browse files
committed
Raise an error if function w/o a $return binding returns a non-None.
Closes issue #74.
1 parent a0277c7 commit 01fe45f

File tree

9 files changed

+35
-4
lines changed

9 files changed

+35
-4
lines changed

azure/worker/dispatcher.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ async def _handle__invocation_request(self, req):
260260
self._sync_call_tp,
261261
self.__run_sync_func, invocation_id, fi.func, args)
262262

263+
if call_result is not None and not fi.has_return:
264+
raise RuntimeError(
265+
f'function {fi.name!r} without a $return binding '
266+
f'returned a non-None value')
267+
263268
output_data = []
264269
if fi.output_types:
265270
for out_name, out_type_info in fi.output_types.items():

azure/worker/functions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class FunctionInfo(typing.NamedTuple):
2121
directory: str
2222
requires_context: bool
2323
is_async: bool
24+
has_return: bool
2425

2526
input_types: typing.Mapping[str, ParamTypeInfo]
2627
output_types: typing.Mapping[str, ParamTypeInfo]
@@ -61,6 +62,7 @@ def add_function(self, function_id: str,
6162
return_pytype: typing.Optional[type] = None
6263

6364
requires_context = False
65+
has_return = False
6466

6567
bound_params = {}
6668
for name, desc in metadata.bindings.items():
@@ -82,6 +84,8 @@ def add_function(self, function_id: str,
8284
raise FunctionLoadError(
8385
func_name,
8486
f'unknown type for $return binding: "{desc.type}"')
87+
88+
has_return = True
8589
else:
8690
bound_params[name] = desc
8791

@@ -199,6 +203,7 @@ def add_function(self, function_id: str,
199203
directory=metadata.directory,
200204
requires_context=requires_context,
201205
is_async=inspect.iscoroutinefunction(func),
206+
has_return=has_return,
202207
input_types=input_types,
203208
output_types=output_types,
204209
return_type=return_type)

tests/blob_functions/ping/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
def main(req):
2-
return 'pong'
2+
return
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"scriptFile": "main.py",
3+
"disabled": false,
4+
"bindings": [
5+
{
6+
"authLevel": "anonymous",
7+
"type": "httpTrigger",
8+
"direction": "in",
9+
"name": "req"
10+
}
11+
]
12+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def main(req):
2+
return 'ABC'

tests/http_functions/ping/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
def main(req):
2-
return 'pong'
2+
return

tests/load_functions/ping/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
def main(req):
2-
return 'pong'
2+
return

tests/queue_functions/ping/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
def main(req):
2-
return 'pong'
2+
return

tests/test_http_functions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ def test_no_return(self):
5151
r = self.webhost.request('GET', 'no_return')
5252
self.assertEqual(r.status_code, 204)
5353

54+
def test_no_return_returns(self):
55+
r = self.webhost.request('GET', 'no_return_returns')
56+
self.assertEqual(r.status_code, 500)
57+
self.assertRegex(r.text,
58+
r'.*function .+no_return_returns.+ without a '
59+
r'\$return binding returned a non-None value.*')
60+
5461
def test_async_return_str(self):
5562
r = self.webhost.request('GET', 'async_return_str')
5663
self.assertEqual(r.status_code, 200)

0 commit comments

Comments
 (0)