mirror of
https://github.com/gradio-app/gradio.git
synced 2024-11-27 01:40:20 +08:00
Make exceptions in the Client more specific (#8264)
* more specific exceptions * format * add changeset * fix * add changeset --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
0bf3d1a992
commit
a9e1a8ac56
6
.changeset/blue-frogs-fetch.md
Normal file
6
.changeset/blue-frogs-fetch.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"gradio": patch
|
||||
"gradio_client": patch
|
||||
---
|
||||
|
||||
feat:Make exceptions in the Client more specific
|
@ -38,7 +38,7 @@ from gradio_client import utils
|
||||
from gradio_client.compatibility import EndpointV3Compatibility
|
||||
from gradio_client.data_classes import ParameterInfo
|
||||
from gradio_client.documentation import document
|
||||
from gradio_client.exceptions import AuthenticationError
|
||||
from gradio_client.exceptions import AppError, AuthenticationError
|
||||
from gradio_client.utils import (
|
||||
Communicator,
|
||||
JobStatus,
|
||||
@ -1216,7 +1216,16 @@ class Endpoint:
|
||||
raise ValueError(f"Unsupported protocol: {self.protocol}")
|
||||
|
||||
if "error" in result:
|
||||
raise ValueError(result["error"])
|
||||
if result["error"] is None:
|
||||
raise AppError(
|
||||
"The upstream Gradio app has raised an exception but has not enabled "
|
||||
"verbose error reporting. To enable, set show_error=True in launch()."
|
||||
)
|
||||
else:
|
||||
raise AppError(
|
||||
"The upstream Gradio app has raised an exception: "
|
||||
+ result["error"]
|
||||
)
|
||||
|
||||
try:
|
||||
output = result["data"]
|
||||
|
@ -8,3 +8,7 @@ class AuthenticationError(ValueError):
|
||||
"""Raised when the client is unable to authenticate itself to a Gradio app due to invalid or missing credentials."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AppError(ValueError):
|
||||
"""Raised when the upstream Gradio app throws an error because of the value submitted by the client."""
|
||||
|
@ -1126,18 +1126,18 @@ def construct_args(
|
||||
for key, value in kwargs.items():
|
||||
if key in kwarg_arg_mapping:
|
||||
if kwarg_arg_mapping[key] < num_args:
|
||||
raise ValueError(
|
||||
raise TypeError(
|
||||
f"Parameter `{key}` is already set as a positional argument. Please click on 'view API' in the footer of the Gradio app to see usage."
|
||||
)
|
||||
else:
|
||||
_args[kwarg_arg_mapping[key]] = value
|
||||
else:
|
||||
raise ValueError(
|
||||
raise TypeError(
|
||||
f"Parameter `{key}` is not a valid key-word argument. Please click on 'view API' in the footer of the Gradio app to see usage."
|
||||
)
|
||||
|
||||
if _Keywords.NO_VALUE in _args:
|
||||
raise ValueError(
|
||||
raise TypeError(
|
||||
f"No value provided for required argument: {kwarg_names[_args.index(_Keywords.NO_VALUE)]}"
|
||||
)
|
||||
|
||||
|
@ -242,7 +242,7 @@ def count_generator_no_api():
|
||||
def count_generator_demo_exception():
|
||||
def count(n):
|
||||
for i in range(int(n)):
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.01)
|
||||
if i == 5:
|
||||
raise ValueError("Oh no!")
|
||||
yield i
|
||||
|
@ -22,7 +22,7 @@ from huggingface_hub.utils import RepositoryNotFoundError
|
||||
|
||||
from gradio_client import Client, file
|
||||
from gradio_client.client import DEFAULT_TEMP_DIR
|
||||
from gradio_client.exceptions import AuthenticationError
|
||||
from gradio_client.exceptions import AppError, AuthenticationError
|
||||
from gradio_client.utils import (
|
||||
Communicator,
|
||||
ProgressUnit,
|
||||
@ -39,9 +39,9 @@ def connect(
|
||||
demo: gr.Blocks,
|
||||
serialize: bool = True,
|
||||
output_dir: str = DEFAULT_TEMP_DIR,
|
||||
max_file_size=None,
|
||||
**kwargs,
|
||||
):
|
||||
_, local_url, _ = demo.launch(prevent_thread_lock=True, max_file_size=max_file_size)
|
||||
_, local_url, _ = demo.launch(prevent_thread_lock=True, **kwargs)
|
||||
try:
|
||||
yield Client(local_url, serialize=serialize, output_dir=output_dir)
|
||||
finally:
|
||||
@ -228,17 +228,6 @@ class TestClientPredictions:
|
||||
outputs.append(o)
|
||||
assert outputs == [str(i) for i in range(3)]
|
||||
|
||||
@pytest.mark.flaky
|
||||
def test_intermediate_outputs_with_exception(self, count_generator_demo_exception):
|
||||
with connect(count_generator_demo_exception) as client:
|
||||
with pytest.raises(Exception):
|
||||
client.predict(7, api_name="/count")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError, match="Cannot call predict on this function"
|
||||
):
|
||||
client.predict(5, api_name="/count_forever")
|
||||
|
||||
def test_break_in_loop_if_error(self, calculator_demo):
|
||||
with connect(calculator_demo) as client:
|
||||
job = client.submit("foo", "add", 4, fn_index=0)
|
||||
@ -682,7 +671,7 @@ class TestClientPredictionsWithKwargs:
|
||||
def test_missing_params(self, calculator_demo):
|
||||
with connect(calculator_demo) as client:
|
||||
with pytest.raises(
|
||||
ValueError, match="No value provided for required argument: num2"
|
||||
TypeError, match="No value provided for required argument: num2"
|
||||
):
|
||||
client.predict(num1=3, operation="add", api_name="/predict")
|
||||
|
||||
@ -1371,3 +1360,21 @@ class TestDuplication:
|
||||
"test_value2",
|
||||
token=HF_TOKEN,
|
||||
)
|
||||
|
||||
|
||||
def test_upstream_exceptions(count_generator_demo_exception):
|
||||
with connect(count_generator_demo_exception, show_error=True) as client:
|
||||
with pytest.raises(
|
||||
AppError, match="The upstream Gradio app has raised an exception: Oh no!"
|
||||
):
|
||||
client.predict(7, api_name="/count")
|
||||
|
||||
with connect(count_generator_demo_exception) as client:
|
||||
with pytest.raises(
|
||||
AppError,
|
||||
match="The upstream Gradio app has raised an exception but has not enabled verbose error reporting.",
|
||||
):
|
||||
client.predict(7, api_name="/count")
|
||||
|
||||
with pytest.raises(ValueError, match="Cannot call predict on this function"):
|
||||
client.predict(5, api_name="/count_forever")
|
||||
|
@ -230,20 +230,20 @@ class TestConstructArgs:
|
||||
def test_positional_arg_and_kwarg_for_same_parameter(self):
|
||||
parameters_info = [{"label": "param1", "parameter_name": "a"}]
|
||||
with pytest.raises(
|
||||
ValueError, match="Parameter `a` is already set as a positional argument."
|
||||
TypeError, match="Parameter `a` is already set as a positional argument."
|
||||
):
|
||||
utils.construct_args(parameters_info, (1,), {"a": 2})
|
||||
|
||||
def test_invalid_kwarg(self):
|
||||
parameters_info = [{"label": "param1", "parameter_name": "a"}]
|
||||
with pytest.raises(
|
||||
ValueError, match="Parameter `b` is not a valid key-word argument."
|
||||
TypeError, match="Parameter `b` is not a valid key-word argument."
|
||||
):
|
||||
utils.construct_args(parameters_info, (), {"b": 1})
|
||||
|
||||
def test_required_arg_missing(self):
|
||||
parameters_info = [{"label": "param1", "parameter_name": "a"}]
|
||||
with pytest.raises(
|
||||
ValueError, match="No value provided for required argument: a"
|
||||
TypeError, match="No value provided for required argument: a"
|
||||
):
|
||||
utils.construct_args(parameters_info, (), {})
|
||||
|
Loading…
Reference in New Issue
Block a user