Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: break retry loop for 401 unauthorized errors in promptnode #4389

Merged
merged 11 commits into from
Mar 17, 2023
17 changes: 17 additions & 0 deletions haystack/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ def __init__(self, message: Optional[str] = None, send_message_in_event: bool =
super().__init__(message=message, status_code=429, send_message_in_event=send_message_in_event)


class OpenAIUnauthorizedError(OpenAIError):
"""
Unauthorized error for OpenAI API (status code 401)
See https://platform.openai.com/docs/guides/error-codes/api-errors
"""

def __init__(self, message: Optional[str] = None, send_message_in_event: bool = False):
super().__init__(message=message, status_code=401, send_message_in_event=send_message_in_event)


class CohereError(NodeError):
"""Exception for issues that occur in the Cohere APIs"""

Expand All @@ -151,6 +161,13 @@ def __init__(
self.status_code = status_code


class CohereUnauthorizedError(CohereError):
"""Exception for unauthorized access to Cohere APIs"""

def __init__(self, message: Optional[str] = None, send_message_in_event: bool = False):
super().__init__(message=message, status_code=401, send_message_in_event=send_message_in_event)


class ImageToTextError(NodeError):
"""Exception for issues that occur in the ImageToText node"""

Expand Down
4 changes: 3 additions & 1 deletion haystack/nodes/retriever/_embedding_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
HAYSTACK_REMOTE_API_MAX_RETRIES,
HAYSTACK_REMOTE_API_TIMEOUT_SEC,
)
from haystack.errors import CohereError
from haystack.errors import CohereError, CohereUnauthorizedError
from haystack.modeling.data_handler.dataloader import NamedDataLoader
from haystack.modeling.data_handler.dataset import convert_features_to_dataset, flatten_rename
from haystack.modeling.infer import Inferencer
Expand Down Expand Up @@ -388,6 +388,8 @@ def embed(self, model: str, text: List[str]) -> np.ndarray:
headers = {"Authorization": f"BEARER {self.api_key}", "Content-Type": "application/json"}
response = requests.request("POST", self.url, headers=headers, data=json.dumps(payload), timeout=COHERE_TIMEOUT)
res = json.loads(response.text)
if response.status_code == 401:
raise CohereUnauthorizedError(f"Invalid Cohere API key. {response.text}")
if response.status_code != 200:
raise CohereError(response.text, status_code=response.status_code)
generated_embeddings = [e for e in res["embeddings"]]
Expand Down
4 changes: 3 additions & 1 deletion haystack/utils/openai_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from transformers import GPT2TokenizerFast

from haystack.errors import OpenAIError, OpenAIRateLimitError
from haystack.errors import OpenAIError, OpenAIRateLimitError, OpenAIUnauthorizedError
from haystack.utils.reflection import retry_with_exponential_backoff
from haystack.environment import (
HAYSTACK_REMOTE_API_BACKOFF_SEC,
Expand Down Expand Up @@ -151,6 +151,8 @@ def openai_request(
openai_error: OpenAIError
if response.status_code == 429:
openai_error = OpenAIRateLimitError(f"API rate limit exceeded: {response.text}")
elif response.status_code == 401:
openai_error = OpenAIUnauthorizedError(f"API key is invalid: {response.text}")
else:
openai_error = OpenAIError(
f"OpenAI returned an error.\n"
Expand Down