見出し画像

エラー発生時に毎回slackに通知を送る #python #slack #jupyter

code by Slack Error Notification (chatgpt.com)

import requests
import sys
import traceback

# SlackのWebhook URL
SLACK_WEBHOOK_URL = 'your-slack-webhook-url'

def send_slack_notification(message: str, webhook_url: str):
    payload = {
        "text": message
    }
    response = requests.post(webhook_url, json=payload)
    if response.status_code != 200:
        raise ValueError(f"Request to Slack returned an error {response.status_code}, the response is:\\n{response.text}")

def setup_exception_handler_with_slack(slack_webhook_url: str):
    # 元の例外フックを保持
    original_excepthook = sys.excepthook

    def handle_exception(exc_type, exc_value, exc_traceback):
        if issubclass(exc_type, KeyboardInterrupt):
            # ユーザーによる中断(Ctrl+C)は無視
            original_excepthook(exc_type, exc_value, exc_traceback)
            return
        
        error_message = f"Error occurred: {str(exc_value)}\\n{''.join(traceback.format_tb(exc_traceback))}"
        send_slack_notification(error_message, slack_webhook_url)
        
        # 元の例外フックを呼び出してデフォルトの例外処理を行う
        original_excepthook(exc_type, exc_value, exc_traceback)

    # デフォルトの例外フックをカスタムフックに置き換え
    sys.excepthook = handle_exception

    # Jupyter環境向けの特別な設定
    def jupyter_exception_handler(shell, etype, evalue, tb, tb_offset=None):
        handle_exception(etype, evalue, tb)
        # Jupyterの標準エラー表示
        shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)

    # Jupyter Notebookであれば、例外ハンドラを設定
    try:
        get_ipython().set_custom_exc((Exception,), jupyter_exception_handler)
    except NameError:
        pass  # Jupyter環境でない場合は何もしない

def main():
    # ここにあなたのメインコードを記述
    # 例として以下にエラーを引き起こすコードを記述
    result = 1 / 0  # ゼロ除算エラー

if __name__ == "__main__":
    # 例外ハンドラを設定
    setup_exception_handler_with_slack(SLACK_WEBHOOK_URL)
    main()

[追記] コード調整

Jupyterだとエラーが2回出力されていたため、調整
tune with Exception Handling Issue (chatgpt.com)

import requests
import sys
import traceback

# SlackのWebhook URL
SLACK_WEBHOOK_URL = 'your-slack-webhook-url'

def send_slack_notification(message: str, webhook_url: str):
    payload = {
        "text": message
    }
    response = requests.post(webhook_url, json=payload)
    if response.status_code != 200:
        raise ValueError(f"Request to Slack returned an error {response.status_code}, the response is:\\n{response.text}")

def setup_exception_handler_with_slack(
    webhook_url: str = os.environ.get("SLACK_WEBHOOK_URL"),
):
    # 元の例外フックを保持
    original_excepthook = sys.excepthook

    def handle_exception(exc_type, exc_value, exc_traceback, skip_original=False):
        if issubclass(exc_type, KeyboardInterrupt):
            # ユーザーによる中断(Ctrl+C)は無視
            original_excepthook(exc_type, exc_value, exc_traceback)
            return

        error_message = f"Error occurred: {str(exc_value)}\\n{''.join(traceback.format_tb(exc_traceback))}"
        send_slack_notification(error_message, webhook_url)

        if not skip_original:
            # 元の例外フックを呼び出してデフォルトの例外処理を行う
            original_excepthook(exc_type, exc_value, exc_traceback)

    # デフォルトの例外フックをカスタムフックに置き換え
    sys.excepthook = handle_exception

    # Jupyter環境向けの特別な設定
    def jupyter_exception_handler(shell, etype, evalue, tb, tb_offset=None):
        handle_exception(etype, evalue, tb, skip_original=True)
        # Jupyterの標準エラー表示
        shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset)

    # Jupyter Notebookであれば、例外ハンドラを設定
    try:
        get_ipython().set_custom_exc((Exception,), jupyter_exception_handler)
    except NameError:
        pass  # Jupyter環境でない場合は何もしない

この記事が気に入ったらサポートをしてみませんか?