Skip to content

Commit

Permalink
Merge pull request #63 from TeskaLabs/Fix/error-messages
Browse files Browse the repository at this point in the history
Fix error messages in kafkahandler
  • Loading branch information
mithunbharadwaj authored Mar 21, 2024
2 parents f0df74b + 1efd846 commit fac9cc9
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 73 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@

- Generate ASABIris error for Email

#### 08. 02. 2024

- Bad templates to be stored in library

#### 08. 02. 2024

- Add ASABIrisError for Teams and slack

#### 12. 02. 2024

- Kafka handler : Fallback solution


### Bugfix

Expand Down
162 changes: 93 additions & 69 deletions asabiris/handlers/kafkahandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,22 @@ async def dispatch(self, msg):
await self.send_email(msg)
except ASABIrisError as e:
# if it is a server error do not send notification.
if e.ErrorCode in [
server_errors = [
ErrorCode.SMTP_CONNECTION_ERROR,
ErrorCode.SMTP_AUTHENTICATION_ERROR,
ErrorCode.SMTP_RESPONSE_ERROR,
ErrorCode.SMTP_SERVER_DISCONNECTED,
ErrorCode.SMTP_GENERIC_ERROR,
ErrorCode.GENERAL_ERROR
]:
L.warning("Failed to send email: Reason {}".format(e))
]
if e.ErrorCode in server_errors:
L.warning("Unable to dispatch email: Explanation {}".format(e.TechMessage))
return
else:
# Handle other errors using handle_exception function
await self.handle_exception(e.TechMessage, 'email', msg)
except Exception as e:
# Handle any other unexpected exceptions using handle_exception function
await self.handle_exception(e, 'email', msg)

elif msg_type == "slack":
Expand All @@ -128,11 +131,13 @@ async def dispatch(self, msg):
except ASABIrisError as e:
# if it is a server error do not send notification.
if e.ErrorCode == ErrorCode.SLACK_API_ERROR:
L.warning("Failed to send notification to slack: Reason: {}".format(e))
L.warning("Notification to Slack unsuccessful: Explanation: {}".format(e.TechMessage))
return
else:
# Handle other errors using handle_exception function
await self.handle_exception(e.TechMessage, 'slack')
except Exception as e:
# Handle any other unexpected exceptions using handle_exception function
await self.handle_exception(e, 'slack')

elif msg_type == "msteams":
Expand All @@ -150,11 +155,13 @@ async def dispatch(self, msg):
except ASABIrisError as e:
# if it is a server error do not send notification.
if e.ErrorCode == ErrorCode.SERVER_ERROR:
L.warning("Failed to send notification to MSTeams: {}".format(e))
L.warning("Notification to MSTeams unsuccessful: Explanation: {}".format(e.TechMessage))
return
else:
# Handle other errors using handle_exception function
await self.handle_exception(e.TechMessage, 'msteams')
except Exception as e:
# Handle any other unexpected exceptions using handle_exception function
await self.handle_exception(e, 'msteams')
else:
L.warning(
Expand All @@ -164,7 +171,7 @@ async def dispatch(self, msg):

async def send_email(self, json_data):
await self.App.SendEmailOrchestrator.send_email(
email_from=json_data['from'],
email_from=json_data.get('from', None),
email_to=json_data['to'],
email_subject=json_data.get('subject', None),
body_template=json_data['body']['template'],
Expand All @@ -175,72 +182,89 @@ async def send_email(self, json_data):
)
L.info("Email sent successfully")


async def handle_exception(self, exception, service_type, msg=None):
# Log the problem first and then send error notification accordingly
L.warning("Following exception occurred while sending '{}'. \n{}".format(service_type, exception))
try:
# Log the problem first and then send error notification accordingly
L.warning("Encountered an issue while sending '{}'. Details: {}.".format(service_type, exception))

error_message, error_subject = self.generate_error_message(str(exception), service_type)
if service_type == 'email' and msg:
try:
await self.App.EmailOutputService.send(
email_from=msg['from'],
email_to=msg['to'],
email_subject=error_subject,
body=error_message
)
except ASABIrisError as e:
L.warning("Failed to send error notification to email. Reason: {}".format(e.TechMessage))
except Exception as e:
L.warning("Failed to send error notification to email. Reason: {}".format(str(e)))
error_message, error_subject = self.generate_error_message(str(exception), service_type)

elif service_type == 'slack':
try:
await self.App.SlackOutputService.send_message(None, error_message)
except ASABIrisError as e:
L.warning("Failed to send error notification to slack. Reason: {}".format(e.TechMessage))
except Exception as e:
L.warning("Failed to send error notification to slack. Reason: {}".format(str(e)))
# Check if error_message is None
if error_message is None:
return

elif service_type == 'msteams':
try:
await self.App.MSTeamsOutputService.send(error_message)
except ASABIrisError as e:
L.warning("Failed to send error notification to MS Teams. Reason: {}".format(e.TechMessage))
except Exception as e:
L.warning("Failed to send error notification to MS Teams. Reason: {}".format(str(e)))
if service_type == 'email' and msg:
try:
L.log(asab.LOG_NOTICE, "Sending error notification to email.")
await self.App.EmailOutputService.send(
email_from=msg.get('from', None),
email_to=msg['to'],
email_subject=error_subject,
body=error_message
)
except ASABIrisError as e:
L.info("Error notification to email unsuccessful: Explanation: {}".format(e.TechMessage))
except Exception:
L.exception("Error notification to email unsuccessful.")

elif service_type == 'slack':
try:
L.log(asab.LOG_NOTICE, "Sending error notification to slack.")
await self.App.SlackOutputService.send_message(None, error_message)
except ASABIrisError as e:
L.info("Error notification to Slack unsuccessful: Explanation: {}".format(e.TechMessage))
except Exception:
L.exception("Error notification to Slack unsuccessful.")

elif service_type == 'msteams':
try:
L.log(asab.LOG_NOTICE, "Sending error notification to MSTeams.")
await self.App.MSTeamsOutputService.send(error_message)
except ASABIrisError as e:
L.info("Error notification to MSTeams unsuccessful: Explanation: {}".format(e.TechMessage))
except Exception:
L.exception("Error notification to MSTeams unsuccessful.")

except Exception:
# Log any unexpected exceptions that might occur
L.exception("An unexpected error occurred while sending error message for {}.".format(service_type))

def generate_error_message(self, specific_error: str, service_type: str):
timestamp = datetime.datetime.now(tz=datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

if service_type == 'email':
error_subject = "Error when generating notification"
error_message = (
"<p>Hello!</p>"
"<p>We encountered an issue while processing your request:<br><b>{}</b></p>"
"<p>Please review your input and try again.<p>"
"<p>Time: {} UTC</p>"
"<p>Best regards,<br>Your Team</p>"
).format(specific_error, timestamp)
return error_message, error_subject

elif service_type == 'slack':
error_message = (
":warning: *Hello!*\n\n"
"We encountered an issue while processing your request:\n`{}`\n\n"
"Please review your input and try again.\n\n"
"*Time:* `{}` UTC\n\n"
"Best regards,\nYour Team :robot_face:"
).format(specific_error, timestamp)
return error_message, None


elif service_type == 'msteams':
error_message = (
"Warning: Hello!\n\n"
"We encountered following issue while processing your request.\n\n`{}`\n\n"
"Please review your input and try again.\n\n"
"Time: `{}` UTC\n\n"
"Best regards,\nYour Team"
).format(specific_error, timestamp)
return error_message, None
try:
timestamp = datetime.datetime.now(tz=datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

if service_type == 'email':
error_subject = "Error Generating Email Notification."
error_message = (
"<p>Hello!</p>"
"<p>We encountered an issue while processing your request:<br><b>{}</b></p>"
"<p>Please review your input and try again.<p>"
"<p>Time: {} UTC</p>"
"<p>Best regards,<br>Your Team</p>"
).format(specific_error, timestamp)
return error_message, error_subject

elif service_type == 'slack':
error_message = (
":warning: *Hello!*\n\n"
"We encountered an issue while processing your request:\n`{}`\n\n"
"Please review your input and try again.\n\n"
"*Time:* `{}` UTC\n\n"
"Best regards,\nYour Team :robot_face:"
).format(specific_error, timestamp)
return error_message, None

elif service_type == 'msteams':
error_message = (
"Warning: Hello!\n\n"
"We encountered following issue while processing your request.\n\n`{}`\n\n"
"Please review your input and try again.\n\n"
"Time: `{}` UTC\n\n"
"Best regards,\nYour Team"
).format(specific_error, timestamp)
return error_message, None

except Exception:
# Log any unexpected exceptions that might occur while generating error message
L.exception("An unexpected error occurred while generating error message.")
return None, None
1 change: 1 addition & 0 deletions asabiris/output/msteams/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ async def send(self, body):
async with aiohttp.ClientSession() as session:
async with session.post(self.TeamsWebhookUrl, json=adaptive_card) as resp:
if resp.status == 200:
L.log(asab.LOG_NOTICE, "MSTeams message sent successfully.")
return True
else:
error_message = await resp.text()
Expand Down
3 changes: 3 additions & 0 deletions asabiris/output/slack/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ async def send_message(self, blocks, fallback_message) -> None:
"error_message": str(e)
}
)
L.log(asab.LOG_NOTICE, "Slack message sent successfully.", struct_data={'channel': self.Channel})

async def send_files(self, body: str, atts_gen):
"""
Expand Down Expand Up @@ -103,6 +104,8 @@ async def send_files(self, body: str, atts_gen):
}
)

L.log(asab.LOG_NOTICE, "Slack message sent successfully.")


def get_channel_id(self, channel_name, types="public_channel"):
# TODO: Cache the channel_id to limit number of requests to Slack API
Expand Down
8 changes: 4 additions & 4 deletions asabiris/output/smtp/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ async def send(
start_tls=self.StartTLS
)
except aiosmtplib.errors.SMTPConnectError as e:
L.info("Connection failed: {}".format(e), struct_data={"host": self.Host, "port": self.Port})
L.warning("Connection failed: {}".format(e), struct_data={"host": self.Host, "port": self.Port})
raise ASABIrisError(
ErrorCode.SMTP_CONNECTION_ERROR,
tech_message="SMTP connection failed: {}.".format(str(e)),
Expand All @@ -151,7 +151,7 @@ async def send(
}
)
except aiosmtplib.errors.SMTPAuthenticationError as e:
L.info("SMTP error: {}".format(e), struct_data={"host": self.Host})
L.warning("SMTP error: {}".format(e), struct_data={"host": self.Host})
raise ASABIrisError(
ErrorCode.SMTP_AUTHENTICATION_ERROR,
tech_message="SMTP authentication error: {}.".format(str(e)),
Expand All @@ -161,7 +161,7 @@ async def send(
}
)
except aiosmtplib.errors.SMTPResponseException as e:
L.info("SMTP Error", struct_data={"message": e.message, "code": e.code, "host": self.Host})
L.warning("SMTP Error", struct_data={"message": e.message, "code": e.code, "host": self.Host})
raise ASABIrisError(
ErrorCode.SMTP_RESPONSE_ERROR,
tech_message="SMTP response exception: Code {}, Message '{}'.".format(e.code, e.message),
Expand All @@ -173,7 +173,7 @@ async def send(
}
)
except aiosmtplib.errors.SMTPServerDisconnected as e:
L.info("Server disconnected: {}; check the SMTP credentials".format(e), struct_data={"host": self.Host})
L.warning("Server disconnected: {}; check the SMTP credentials".format(e), struct_data={"host": self.Host})
raise ASABIrisError(
ErrorCode.SMTP_SERVER_DISCONNECTED,
tech_message="SMTP server disconnected: {}.".format(str(e)),
Expand Down

0 comments on commit fac9cc9

Please sign in to comment.