error-reporter 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- error_reporter-0.0.0/PKG-INFO +100 -0
- error_reporter-0.0.0/README.md +83 -0
- error_reporter-0.0.0/error_reporter/__init__.py +8 -0
- error_reporter-0.0.0/error_reporter/core/__init__.py +5 -0
- error_reporter-0.0.0/error_reporter/core/core_client.py +15 -0
- error_reporter-0.0.0/error_reporter/core/discord_client.py +34 -0
- error_reporter-0.0.0/error_reporter/core/error_message_format_helper.py +43 -0
- error_reporter-0.0.0/error_reporter/core/github_client.py +94 -0
- error_reporter-0.0.0/error_reporter/core/google_chat_client.py +5 -0
- error_reporter-0.0.0/error_reporter/core/slack_client.py +36 -0
- error_reporter-0.0.0/error_reporter/error_reporter_options.py +19 -0
- error_reporter-0.0.0/error_reporter/init_app.py +11 -0
- error_reporter-0.0.0/error_reporter/service/__init__.py +0 -0
- error_reporter-0.0.0/error_reporter/service/error_reporter_filter.py +52 -0
- error_reporter-0.0.0/error_reporter/service/error_reporter_service_container.py +53 -0
- error_reporter-0.0.0/error_reporter/types/message_builder_option.py +11 -0
- error_reporter-0.0.0/error_reporter.egg-info/PKG-INFO +100 -0
- error_reporter-0.0.0/error_reporter.egg-info/SOURCES.txt +21 -0
- error_reporter-0.0.0/error_reporter.egg-info/dependency_links.txt +1 -0
- error_reporter-0.0.0/error_reporter.egg-info/requires.txt +3 -0
- error_reporter-0.0.0/error_reporter.egg-info/top_level.txt +2 -0
- error_reporter-0.0.0/pyproject.toml +47 -0
- error_reporter-0.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: error-reporter
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A lightweight fastapi library for reporting application errors and exceptions to external application.
|
|
5
|
+
Author-email: Seungkyu-Han <trust1204@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Seungkyu-Han/error-reporter-python
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/Seungkyu-Han/error-reporter-python/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/Seungkyu-Han/error-reporter-python#readme
|
|
10
|
+
Project-URL: Source, https://github.com/Seungkyu-Han/error-reporter-python
|
|
11
|
+
Keywords: error,report
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: fastapi>=0.135.2
|
|
15
|
+
Requires-Dist: aiohttp>=3.13.4
|
|
16
|
+
Requires-Dist: certifi>=2026.2.25
|
|
17
|
+
|
|
18
|
+
# Error Reporter for Fast API
|
|
19
|
+
|
|
20
|
+
[](https://pypi.org/project/error-reporter/)
|
|
21
|
+

|
|
22
|
+

|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
A python library for Fast API that sends error reports to messaging platforms like Slack.
|
|
26
|
+
|
|
27
|
+
When an error other than an HttpException occurs on the server. it is reported according to the configured settings.
|
|
28
|
+
|
|
29
|
+
Installation
|
|
30
|
+
|
|
31
|
+
```shell
|
|
32
|
+
pip install error-reporter
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### configuration
|
|
38
|
+
```python
|
|
39
|
+
from error_reporter import init_error_reporter, SlackOptions
|
|
40
|
+
|
|
41
|
+
from fastapi import FastAPI
|
|
42
|
+
|
|
43
|
+
app = FastAPI()
|
|
44
|
+
|
|
45
|
+
init_error_reporter(
|
|
46
|
+
app=app,
|
|
47
|
+
options=SlackOptions(
|
|
48
|
+
webhook_url='',
|
|
49
|
+
server_name='',
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
##### slack, discord, google-chat
|
|
55
|
+
|
|
56
|
+
| Option | Type | Required | Default | Description |
|
|
57
|
+
|------------|-----------------------------------|----------|----------------|--------------------------------------|
|
|
58
|
+
| type | 'slack', 'discord', 'google-chat' | ✅ | - | type of messenger |
|
|
59
|
+
| webhookUrl | string | ✅ | - | Slack webhook URL to send error logs |
|
|
60
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
61
|
+
|
|
62
|
+
##### github
|
|
63
|
+
|
|
64
|
+
| Option | Type | Required | Default | Description |
|
|
65
|
+
|-------------|----------|----------|----------------|----------------------------------------------|
|
|
66
|
+
| type | 'github' | ✅ | - | type of messenger |
|
|
67
|
+
| githubToken | string | ✅ | - | GitHub personal access token |
|
|
68
|
+
| owner | string | ✅ | - | Repository owner (user or organization) |
|
|
69
|
+
| repository | string | ✅ | - | Repository name where issues will be created |
|
|
70
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
❗Warning
|
|
74
|
+
|
|
75
|
+
If an invalid or unauthorized token is provided, the application will fail to start.
|
|
76
|
+
|
|
77
|
+
The server will also fail to start if any of the required GitHub configuration values are missing or incorrect,
|
|
78
|
+
including:
|
|
79
|
+
|
|
80
|
+
## Example
|
|
81
|
+
|
|
82
|
+
### slack
|
|
83
|
+
|
|
84
|
+

|
|
85
|
+
|
|
86
|
+
### discord
|
|
87
|
+
|
|
88
|
+

|
|
89
|
+
|
|
90
|
+
### google-chat
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
### github
|
|
95
|
+
|
|
96
|
+

|
|
97
|
+
|
|
98
|
+
## Contact
|
|
99
|
+
|
|
100
|
+
- Email: [trust1204@gmail.com](mailto:trust1204@gmail.com)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Error Reporter for Fast API
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/error-reporter/)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
A python library for Fast API that sends error reports to messaging platforms like Slack.
|
|
9
|
+
|
|
10
|
+
When an error other than an HttpException occurs on the server. it is reported according to the configured settings.
|
|
11
|
+
|
|
12
|
+
Installation
|
|
13
|
+
|
|
14
|
+
```shell
|
|
15
|
+
pip install error-reporter
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### configuration
|
|
21
|
+
```python
|
|
22
|
+
from error_reporter import init_error_reporter, SlackOptions
|
|
23
|
+
|
|
24
|
+
from fastapi import FastAPI
|
|
25
|
+
|
|
26
|
+
app = FastAPI()
|
|
27
|
+
|
|
28
|
+
init_error_reporter(
|
|
29
|
+
app=app,
|
|
30
|
+
options=SlackOptions(
|
|
31
|
+
webhook_url='',
|
|
32
|
+
server_name='',
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
##### slack, discord, google-chat
|
|
38
|
+
|
|
39
|
+
| Option | Type | Required | Default | Description |
|
|
40
|
+
|------------|-----------------------------------|----------|----------------|--------------------------------------|
|
|
41
|
+
| type | 'slack', 'discord', 'google-chat' | ✅ | - | type of messenger |
|
|
42
|
+
| webhookUrl | string | ✅ | - | Slack webhook URL to send error logs |
|
|
43
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
44
|
+
|
|
45
|
+
##### github
|
|
46
|
+
|
|
47
|
+
| Option | Type | Required | Default | Description |
|
|
48
|
+
|-------------|----------|----------|----------------|----------------------------------------------|
|
|
49
|
+
| type | 'github' | ✅ | - | type of messenger |
|
|
50
|
+
| githubToken | string | ✅ | - | GitHub personal access token |
|
|
51
|
+
| owner | string | ✅ | - | Repository owner (user or organization) |
|
|
52
|
+
| repository | string | ✅ | - | Repository name where issues will be created |
|
|
53
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
❗Warning
|
|
57
|
+
|
|
58
|
+
If an invalid or unauthorized token is provided, the application will fail to start.
|
|
59
|
+
|
|
60
|
+
The server will also fail to start if any of the required GitHub configuration values are missing or incorrect,
|
|
61
|
+
including:
|
|
62
|
+
|
|
63
|
+
## Example
|
|
64
|
+
|
|
65
|
+
### slack
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
### discord
|
|
70
|
+
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
### google-chat
|
|
74
|
+
|
|
75
|
+

|
|
76
|
+
|
|
77
|
+
### github
|
|
78
|
+
|
|
79
|
+

|
|
80
|
+
|
|
81
|
+
## Contact
|
|
82
|
+
|
|
83
|
+
- Email: [trust1204@gmail.com](mailto:trust1204@gmail.com)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import certifi
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
class CoreClient(ABC):
|
|
6
|
+
_client: httpx.AsyncClient = None
|
|
7
|
+
|
|
8
|
+
async def _get_client(self) -> httpx.AsyncClient:
|
|
9
|
+
if self._client is None or self._client.is_closed:
|
|
10
|
+
self._client = httpx.AsyncClient(verify=certifi.where())
|
|
11
|
+
return self._client
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
async def report(self, message_builder_option):
|
|
15
|
+
...
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from error_reporter.core.core_client import CoreClient
|
|
4
|
+
from error_reporter.core.error_message_format_helper import ErrorMessageFormatHelper
|
|
5
|
+
from error_reporter.types.message_builder_option import MessageBuilderOption
|
|
6
|
+
|
|
7
|
+
class DiscordClient(CoreClient):
|
|
8
|
+
|
|
9
|
+
def __init__(self, webhook_url: str, error_message_format_helper: ErrorMessageFormatHelper):
|
|
10
|
+
self._webhook_url = webhook_url
|
|
11
|
+
self._error_message_format_helper = error_message_format_helper
|
|
12
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
|
13
|
+
|
|
14
|
+
async def report(self, message_builder_option: MessageBuilderOption):
|
|
15
|
+
send_message: str = self._error_message_format_helper.error_message(
|
|
16
|
+
message_builder_option=message_builder_option
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
client = await self._get_client()
|
|
21
|
+
|
|
22
|
+
response = await client.post(
|
|
23
|
+
self._webhook_url,
|
|
24
|
+
json={"content": send_message},
|
|
25
|
+
headers={"Content-Type": "application/json"}
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if response.is_success:
|
|
29
|
+
self._logger.info("error_reporter send error success")
|
|
30
|
+
else:
|
|
31
|
+
self._logger.error("discord send failed: status=%s", response.status_code)
|
|
32
|
+
|
|
33
|
+
except Exception as ex:
|
|
34
|
+
self._logger.error(f"error reporter fail to send: {ex}")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from error_reporter.types.message_builder_option import MessageBuilderOption
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ErrorMessageFormatHelper:
|
|
9
|
+
|
|
10
|
+
def __init__(self, server_name: str = None):
|
|
11
|
+
self._server_name: str = server_name or "unknown server"
|
|
12
|
+
|
|
13
|
+
def error_message(
|
|
14
|
+
self,
|
|
15
|
+
message_builder_option: MessageBuilderOption,
|
|
16
|
+
) -> str:
|
|
17
|
+
method = message_builder_option.method
|
|
18
|
+
path = message_builder_option.path
|
|
19
|
+
ip = message_builder_option.ip
|
|
20
|
+
error = message_builder_option.error
|
|
21
|
+
stack = message_builder_option.stack
|
|
22
|
+
|
|
23
|
+
stack_content = (
|
|
24
|
+
"\n".join(stack.split("\n")) + "\n..."
|
|
25
|
+
if stack else "No stack trace available"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return f"""
|
|
29
|
+
🔥 *[{self._server_name}] Unhandled Exception*
|
|
30
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
31
|
+
|
|
32
|
+
*📍 Request Information*
|
|
33
|
+
- *Method:* `{method}`
|
|
34
|
+
- *Path:* `{path}`
|
|
35
|
+
- *IP:* `{ip}`
|
|
36
|
+
- *Timestamp:* `{datetime.now().isoformat()}`
|
|
37
|
+
|
|
38
|
+
❌ Error Message
|
|
39
|
+
{error}
|
|
40
|
+
|
|
41
|
+
📜 Stack Trace
|
|
42
|
+
{stack_content}
|
|
43
|
+
"""
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from error_reporter.core.core_client import CoreClient
|
|
4
|
+
from error_reporter.core.error_message_format_helper import ErrorMessageFormatHelper
|
|
5
|
+
from error_reporter.types.message_builder_option import MessageBuilderOption
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GithubClient(CoreClient):
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
github_token: str,
|
|
13
|
+
repository: str,
|
|
14
|
+
owner: str,
|
|
15
|
+
error_message_format_helper: ErrorMessageFormatHelper,
|
|
16
|
+
):
|
|
17
|
+
self._github_token = github_token
|
|
18
|
+
self._repository = repository
|
|
19
|
+
self._owner = owner
|
|
20
|
+
self._error_message_format_helper = error_message_format_helper
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
async def create(
|
|
24
|
+
cls,
|
|
25
|
+
github_token: str,
|
|
26
|
+
repository: str,
|
|
27
|
+
owner: str,
|
|
28
|
+
error_message_format_helper: ErrorMessageFormatHelper,
|
|
29
|
+
):
|
|
30
|
+
self = cls(github_token, repository, owner, error_message_format_helper)
|
|
31
|
+
await self.check_github_access()
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
async def check_github_access(self):
|
|
35
|
+
url = f"https://api.github.com/repos/{self._owner}/{self._repository}/issues"
|
|
36
|
+
|
|
37
|
+
headers = {
|
|
38
|
+
"Accept": "application/vnd.github+json",
|
|
39
|
+
"Authorization": f"Bearer {self._github_token}",
|
|
40
|
+
"X-GitHub-Api-Version": "2026-03-10",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
client = await self._get_client()
|
|
44
|
+
|
|
45
|
+
response = await client.get(
|
|
46
|
+
url,
|
|
47
|
+
headers=headers,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if not response.is_success:
|
|
51
|
+
if response.status_code == 404:
|
|
52
|
+
raise Exception("GitHub Not Found: Invalid repository or owner")
|
|
53
|
+
else:
|
|
54
|
+
raise Exception(f"GitHub API Error: {response.status_code}")
|
|
55
|
+
|
|
56
|
+
async def report(self, message_builder_option: MessageBuilderOption):
|
|
57
|
+
url = f"https://api.github.com/repos/{self._owner}/{self._repository}/issues"
|
|
58
|
+
|
|
59
|
+
title = f"[FIX] {message_builder_option.error}"
|
|
60
|
+
body = self._error_message_format_helper.error_message(message_builder_option)
|
|
61
|
+
|
|
62
|
+
headers = {
|
|
63
|
+
"Authorization": f"Bearer {self._github_token}",
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
payload = {
|
|
68
|
+
"title": title,
|
|
69
|
+
"body": body,
|
|
70
|
+
"labels": ["bug"],
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
client = await self._get_client()
|
|
74
|
+
|
|
75
|
+
response = await client.post(
|
|
76
|
+
url,
|
|
77
|
+
headers=headers,
|
|
78
|
+
json=payload,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if not response.is_success:
|
|
82
|
+
|
|
83
|
+
if response.status_code == 403:
|
|
84
|
+
logging.error(
|
|
85
|
+
"ErrorReporter: Insufficient permissions or rate limit exceeded, Please check your github token"
|
|
86
|
+
)
|
|
87
|
+
elif response.status_code == 404:
|
|
88
|
+
logging.error(
|
|
89
|
+
"ErrorReporter: Invalid repository or owner"
|
|
90
|
+
)
|
|
91
|
+
else:
|
|
92
|
+
logging.error(
|
|
93
|
+
f"ErrorReporter: {response.status_code}"
|
|
94
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from error_reporter.core.core_client import CoreClient
|
|
4
|
+
from error_reporter.core.error_message_format_helper import ErrorMessageFormatHelper
|
|
5
|
+
from error_reporter.types.message_builder_option import MessageBuilderOption
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SlackClient(CoreClient):
|
|
11
|
+
|
|
12
|
+
def __init__(self, webhook_url: str, error_message_format_helper: ErrorMessageFormatHelper):
|
|
13
|
+
self._webhook_url = webhook_url
|
|
14
|
+
self._error_message_format_helper = error_message_format_helper
|
|
15
|
+
self._logger = logging.getLogger(self.__class__.__name__)
|
|
16
|
+
|
|
17
|
+
async def report(self, message_builder_option: MessageBuilderOption):
|
|
18
|
+
send_message: str = self._error_message_format_helper.error_message(
|
|
19
|
+
message_builder_option=message_builder_option)
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
client = await self._get_client()
|
|
23
|
+
|
|
24
|
+
response = await client.post(
|
|
25
|
+
self._webhook_url,
|
|
26
|
+
json={"text": send_message},
|
|
27
|
+
headers={"Content-Type": "application/json"}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if response.is_success:
|
|
31
|
+
self._logger.info("error_reporter send error success")
|
|
32
|
+
else:
|
|
33
|
+
self._logger.error("slack send failed: status=%s", response.status_code)
|
|
34
|
+
|
|
35
|
+
except Exception as ex:
|
|
36
|
+
logger.error(f"error reporter fail to send: {ex}")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
class SlackOptions(BaseModel):
|
|
4
|
+
webhook_url: str
|
|
5
|
+
server_name: str = "unknown server"
|
|
6
|
+
|
|
7
|
+
class DiscordOptions(BaseModel):
|
|
8
|
+
webhook_url: str
|
|
9
|
+
server_name: str = "unknown server"
|
|
10
|
+
|
|
11
|
+
class GoogleChatOptions(BaseModel):
|
|
12
|
+
webhook_url: str
|
|
13
|
+
server_name: str = "unknown server"
|
|
14
|
+
|
|
15
|
+
class GithubOptions(BaseModel):
|
|
16
|
+
github_token: str
|
|
17
|
+
owner: str
|
|
18
|
+
repository: str
|
|
19
|
+
server_name: str = "unknown server"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
from fastapi import FastAPI
|
|
3
|
+
|
|
4
|
+
from error_reporter.service.error_reporter_filter import error_reporter_filter
|
|
5
|
+
from error_reporter.service.error_reporter_service_container import get_client
|
|
6
|
+
from .error_reporter_options import SlackOptions, DiscordOptions
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def init_error_reporter(app: FastAPI, options: Union[SlackOptions, DiscordOptions]):
|
|
10
|
+
setattr(app.state, 'error_reporter_client', get_client(options)) # type: ignore[attr-defined]
|
|
11
|
+
app.middleware('http')(error_reporter_filter)
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
|
|
3
|
+
from fastapi import Request, Response, HTTPException, status
|
|
4
|
+
|
|
5
|
+
from error_reporter.core.core_client import CoreClient
|
|
6
|
+
from error_reporter.types.message_builder_option import MessageBuilderOption
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def error_reporter_filter(request: Request, call_next):
|
|
10
|
+
client: CoreClient = request.app.state.error_reporter_client
|
|
11
|
+
|
|
12
|
+
if client is None:
|
|
13
|
+
return await call_next(request)
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
return await call_next(request)
|
|
17
|
+
|
|
18
|
+
except HTTPException:
|
|
19
|
+
raise
|
|
20
|
+
|
|
21
|
+
except Exception as exception:
|
|
22
|
+
|
|
23
|
+
method: str = request.method
|
|
24
|
+
path: str = str(request.url)
|
|
25
|
+
|
|
26
|
+
x_forwarded_for = request.headers.get("x-forwarded-for")
|
|
27
|
+
|
|
28
|
+
if x_forwarded_for:
|
|
29
|
+
ip = x_forwarded_for.split(",")[0].strip()
|
|
30
|
+
else:
|
|
31
|
+
ip = request.client.host
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
error = str(exception)
|
|
36
|
+
|
|
37
|
+
stack = traceback.format_exc()
|
|
38
|
+
|
|
39
|
+
message_builder_option = MessageBuilderOption(
|
|
40
|
+
method=method,
|
|
41
|
+
path=path,
|
|
42
|
+
ip=ip,
|
|
43
|
+
error=error,
|
|
44
|
+
stack=stack
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
await client.report(message_builder_option=message_builder_option)
|
|
48
|
+
|
|
49
|
+
return Response(
|
|
50
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
51
|
+
content="Internal Server Error"
|
|
52
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
from error_reporter.core.core_client import CoreClient
|
|
4
|
+
from error_reporter.core.error_message_format_helper import ErrorMessageFormatHelper
|
|
5
|
+
from error_reporter.error_reporter_options import GoogleChatOptions, GithubOptions, SlackOptions, DiscordOptions
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_client(
|
|
9
|
+
options: Union[SlackOptions, DiscordOptions, GoogleChatOptions, GithubOptions]
|
|
10
|
+
) -> CoreClient:
|
|
11
|
+
error_message_format_helper = ErrorMessageFormatHelper(
|
|
12
|
+
server_name=options.server_name,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
if isinstance(options, SlackOptions):
|
|
16
|
+
|
|
17
|
+
from error_reporter.core.slack_client import SlackClient
|
|
18
|
+
|
|
19
|
+
return SlackClient(
|
|
20
|
+
webhook_url=options.webhook_url,
|
|
21
|
+
error_message_format_helper=error_message_format_helper,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
elif isinstance(options, DiscordOptions):
|
|
25
|
+
|
|
26
|
+
from error_reporter.core.discord_client import DiscordClient
|
|
27
|
+
|
|
28
|
+
return DiscordClient(
|
|
29
|
+
webhook_url=options.webhook_url,
|
|
30
|
+
error_message_format_helper=error_message_format_helper,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
elif isinstance(options, GoogleChatOptions):
|
|
34
|
+
|
|
35
|
+
from error_reporter.core.google_chat_client import GoogleChatClient
|
|
36
|
+
|
|
37
|
+
return GoogleChatClient(
|
|
38
|
+
webhook_url=options.webhook_url,
|
|
39
|
+
error_message_format_helper=error_message_format_helper,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
elif isinstance(options, GithubOptions):
|
|
43
|
+
|
|
44
|
+
from error_reporter.core.github_client import GithubClient
|
|
45
|
+
|
|
46
|
+
return GithubClient(
|
|
47
|
+
github_token=options.github_token,
|
|
48
|
+
owner=options.owner,
|
|
49
|
+
repository=options.repository,
|
|
50
|
+
error_message_format_helper=error_message_format_helper,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
raise Exception('invalid type')
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: error-reporter
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A lightweight fastapi library for reporting application errors and exceptions to external application.
|
|
5
|
+
Author-email: Seungkyu-Han <trust1204@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Seungkyu-Han/error-reporter-python
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/Seungkyu-Han/error-reporter-python/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/Seungkyu-Han/error-reporter-python#readme
|
|
10
|
+
Project-URL: Source, https://github.com/Seungkyu-Han/error-reporter-python
|
|
11
|
+
Keywords: error,report
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: fastapi>=0.135.2
|
|
15
|
+
Requires-Dist: aiohttp>=3.13.4
|
|
16
|
+
Requires-Dist: certifi>=2026.2.25
|
|
17
|
+
|
|
18
|
+
# Error Reporter for Fast API
|
|
19
|
+
|
|
20
|
+
[](https://pypi.org/project/error-reporter/)
|
|
21
|
+

|
|
22
|
+

|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
A python library for Fast API that sends error reports to messaging platforms like Slack.
|
|
26
|
+
|
|
27
|
+
When an error other than an HttpException occurs on the server. it is reported according to the configured settings.
|
|
28
|
+
|
|
29
|
+
Installation
|
|
30
|
+
|
|
31
|
+
```shell
|
|
32
|
+
pip install error-reporter
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### configuration
|
|
38
|
+
```python
|
|
39
|
+
from error_reporter import init_error_reporter, SlackOptions
|
|
40
|
+
|
|
41
|
+
from fastapi import FastAPI
|
|
42
|
+
|
|
43
|
+
app = FastAPI()
|
|
44
|
+
|
|
45
|
+
init_error_reporter(
|
|
46
|
+
app=app,
|
|
47
|
+
options=SlackOptions(
|
|
48
|
+
webhook_url='',
|
|
49
|
+
server_name='',
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
##### slack, discord, google-chat
|
|
55
|
+
|
|
56
|
+
| Option | Type | Required | Default | Description |
|
|
57
|
+
|------------|-----------------------------------|----------|----------------|--------------------------------------|
|
|
58
|
+
| type | 'slack', 'discord', 'google-chat' | ✅ | - | type of messenger |
|
|
59
|
+
| webhookUrl | string | ✅ | - | Slack webhook URL to send error logs |
|
|
60
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
61
|
+
|
|
62
|
+
##### github
|
|
63
|
+
|
|
64
|
+
| Option | Type | Required | Default | Description |
|
|
65
|
+
|-------------|----------|----------|----------------|----------------------------------------------|
|
|
66
|
+
| type | 'github' | ✅ | - | type of messenger |
|
|
67
|
+
| githubToken | string | ✅ | - | GitHub personal access token |
|
|
68
|
+
| owner | string | ✅ | - | Repository owner (user or organization) |
|
|
69
|
+
| repository | string | ✅ | - | Repository name where issues will be created |
|
|
70
|
+
| serverName | string | ❌ | unknown server | Identifier for the server |
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
❗Warning
|
|
74
|
+
|
|
75
|
+
If an invalid or unauthorized token is provided, the application will fail to start.
|
|
76
|
+
|
|
77
|
+
The server will also fail to start if any of the required GitHub configuration values are missing or incorrect,
|
|
78
|
+
including:
|
|
79
|
+
|
|
80
|
+
## Example
|
|
81
|
+
|
|
82
|
+
### slack
|
|
83
|
+
|
|
84
|
+

|
|
85
|
+
|
|
86
|
+
### discord
|
|
87
|
+
|
|
88
|
+

|
|
89
|
+
|
|
90
|
+
### google-chat
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
### github
|
|
95
|
+
|
|
96
|
+

|
|
97
|
+
|
|
98
|
+
## Contact
|
|
99
|
+
|
|
100
|
+
- Email: [trust1204@gmail.com](mailto:trust1204@gmail.com)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
error_reporter/__init__.py
|
|
4
|
+
error_reporter/error_reporter_options.py
|
|
5
|
+
error_reporter/init_app.py
|
|
6
|
+
error_reporter.egg-info/PKG-INFO
|
|
7
|
+
error_reporter.egg-info/SOURCES.txt
|
|
8
|
+
error_reporter.egg-info/dependency_links.txt
|
|
9
|
+
error_reporter.egg-info/requires.txt
|
|
10
|
+
error_reporter.egg-info/top_level.txt
|
|
11
|
+
error_reporter/core/__init__.py
|
|
12
|
+
error_reporter/core/core_client.py
|
|
13
|
+
error_reporter/core/discord_client.py
|
|
14
|
+
error_reporter/core/error_message_format_helper.py
|
|
15
|
+
error_reporter/core/github_client.py
|
|
16
|
+
error_reporter/core/google_chat_client.py
|
|
17
|
+
error_reporter/core/slack_client.py
|
|
18
|
+
error_reporter/service/__init__.py
|
|
19
|
+
error_reporter/service/error_reporter_filter.py
|
|
20
|
+
error_reporter/service/error_reporter_service_container.py
|
|
21
|
+
error_reporter/types/message_builder_option.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "error-reporter"
|
|
7
|
+
version = "0.0.0"
|
|
8
|
+
description = "A lightweight fastapi library for reporting application errors and exceptions to external application."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
keywords = [
|
|
13
|
+
"error",
|
|
14
|
+
"report"
|
|
15
|
+
]
|
|
16
|
+
authors = [
|
|
17
|
+
{ name = "Seungkyu-Han", email = "trust1204@gmail.com" }
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"fastapi>=0.135.2",
|
|
21
|
+
"aiohttp>=3.13.4",
|
|
22
|
+
"certifi>=2026.2.25"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
githu-actions = [
|
|
27
|
+
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
"Homepage" = "https://github.com/Seungkyu-Han/error-reporter-python"
|
|
32
|
+
"Bug Tracker" = "https://github.com/Seungkyu-Han/error-reporter-python/issues"
|
|
33
|
+
"Documentation" = "https://github.com/Seungkyu-Han/error-reporter-python#readme"
|
|
34
|
+
"Source" = "https://github.com/Seungkyu-Han/error-reporter-python"
|
|
35
|
+
|
|
36
|
+
[tool.pytest.ini_options]
|
|
37
|
+
testpaths = ["tests"]
|
|
38
|
+
asyncio_mode = "auto"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
[tool.black]
|
|
42
|
+
line-length = 100
|
|
43
|
+
target-version = ['py310', 'py311']
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["."]
|