Skip to content

Commit 204bb1c

Browse files
authored
Add special error (#896)
1 parent 7414491 commit 204bb1c

File tree

8 files changed

+84
-4
lines changed

8 files changed

+84
-4
lines changed

app/backend/app.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
If you are an administrator of the app, view the full error in the logs. See aka.ms/appservice-logs for more information.
4545
Error type: {error_type}
4646
"""
47+
ERROR_MESSAGE_FILTER = """Your message contains content that was flagged by the OpenAI content filter."""
4748

4849
bp = Blueprint("routes", __name__, static_folder="static")
4950
# Fix Windows registry issue with mimetypes
@@ -101,9 +102,18 @@ async def content_file(path: str):
101102

102103

103104
def error_dict(error: Exception) -> dict:
105+
if isinstance(error, openai.error.InvalidRequestError) and error.code == "content_filter":
106+
return {"error": ERROR_MESSAGE_FILTER}
104107
return {"error": ERROR_MESSAGE.format(error_type=type(error))}
105108

106109

110+
def error_response(error: Exception, route: str, status_code: int = 500):
111+
logging.exception("Exception in %s: %s", route, error)
112+
if isinstance(error, openai.error.InvalidRequestError) and error.code == "content_filter":
113+
status_code = 400
114+
return jsonify(error_dict(error)), status_code
115+
116+
107117
@bp.route("/ask", methods=["POST"])
108118
async def ask():
109119
if not request.is_json:
@@ -122,8 +132,7 @@ async def ask():
122132
)
123133
return jsonify(r)
124134
except Exception as error:
125-
logging.exception("Exception in /ask: %s", error)
126-
return jsonify(error_dict(error)), 500
135+
return error_response(error, "/ask")
127136

128137

129138
async def format_as_ndjson(r: AsyncGenerator[dict, None]) -> AsyncGenerator[str, None]:
@@ -158,8 +167,7 @@ async def chat():
158167
response.timeout = None # type: ignore
159168
return response
160169
except Exception as error:
161-
logging.exception("Exception in /chat: %s", error)
162-
return jsonify(error_dict(error)), 500
170+
return error_response(error, "/chat")
163171

164172

165173
# Send MSAL.js settings to the client UI
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error": "Your message contains content that was flagged by the OpenAI content filter."
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error": "Your message contains content that was flagged by the OpenAI content filter."
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error": "Your message contains content that was flagged by the OpenAI content filter."
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error": "Your message contains content that was flagged by the OpenAI content filter."
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"error": "Your message contains content that was flagged by the OpenAI content filter."}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"error": "Your message contains content that was flagged by the OpenAI content filter."}

tests/test_app.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
from unittest import mock
55

6+
import openai
67
import pytest
78
import quart.testing.app
89

@@ -63,6 +64,25 @@ async def test_ask_handle_exception(client, monkeypatch, snapshot, caplog):
6364
snapshot.assert_match(json.dumps(result, indent=4), "result.json")
6465

6566

67+
@pytest.mark.asyncio
68+
async def test_ask_handle_exception_contentsafety(client, monkeypatch, snapshot, caplog):
69+
monkeypatch.setattr(
70+
"approaches.retrievethenread.RetrieveThenReadApproach.run",
71+
mock.Mock(
72+
side_effect=openai.error.InvalidRequestError("The response was filtered", "prompt", code="content_filter")
73+
),
74+
)
75+
76+
response = await client.post(
77+
"/ask",
78+
json={"messages": [{"content": "How do I do something bad?", "role": "user"}]},
79+
)
80+
assert response.status_code == 400
81+
result = await response.get_json()
82+
assert "Exception in /ask: The response was filtered" in caplog.text
83+
snapshot.assert_match(json.dumps(result, indent=4), "result.json")
84+
85+
6686
@pytest.mark.asyncio
6787
async def test_ask_rtr_text(client, snapshot):
6888
response = await client.post(
@@ -178,6 +198,25 @@ async def test_chat_handle_exception(client, monkeypatch, snapshot, caplog):
178198
snapshot.assert_match(json.dumps(result, indent=4), "result.json")
179199

180200

201+
@pytest.mark.asyncio
202+
async def test_chat_handle_exception_contentsafety(client, monkeypatch, snapshot, caplog):
203+
monkeypatch.setattr(
204+
"approaches.chatreadretrieveread.ChatReadRetrieveReadApproach.run",
205+
mock.Mock(
206+
side_effect=openai.error.InvalidRequestError("The response was filtered", "prompt", code="content_filter")
207+
),
208+
)
209+
210+
response = await client.post(
211+
"/chat",
212+
json={"messages": [{"content": "How do I do something bad?", "role": "user"}]},
213+
)
214+
assert response.status_code == 400
215+
result = await response.get_json()
216+
assert "Exception in /chat: The response was filtered" in caplog.text
217+
snapshot.assert_match(json.dumps(result, indent=4), "result.json")
218+
219+
181220
@pytest.mark.asyncio
182221
async def test_chat_handle_exception_streaming(client, monkeypatch, snapshot, caplog):
183222
monkeypatch.setattr(
@@ -194,6 +233,25 @@ async def test_chat_handle_exception_streaming(client, monkeypatch, snapshot, ca
194233
snapshot.assert_match(result, "result.jsonlines")
195234

196235

236+
@pytest.mark.asyncio
237+
async def test_chat_handle_exception_contentsafety_streaming(client, monkeypatch, snapshot, caplog):
238+
monkeypatch.setattr(
239+
"openai.ChatCompletion.acreate",
240+
mock.Mock(
241+
side_effect=openai.error.InvalidRequestError("The response was filtered", "prompt", code="content_filter")
242+
),
243+
)
244+
245+
response = await client.post(
246+
"/chat",
247+
json={"messages": [{"content": "How do I do something bad?", "role": "user"}], "stream": True},
248+
)
249+
assert response.status_code == 200
250+
assert "Exception while generating response stream: The response was filtered" in caplog.text
251+
result = await response.get_data()
252+
snapshot.assert_match(result, "result.jsonlines")
253+
254+
197255
@pytest.mark.asyncio
198256
async def test_chat_text(client, snapshot):
199257
response = await client.post(

0 commit comments

Comments
 (0)