errors.ErrorsCog.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
"""Cogs that handles errors"""
2
import random
3
from datetime import datetime
4
5
import discord
6
from discord.ext import commands
7
from bot import utils
8
import cyberjake
9
10
11
class ErrorsCog(commands.Cog, name="Errors"):
12
    """ErrorsCogs
13
    ---
14
15
    The cog that handles all errors.
16
17
    Commands:
18
    ---
19
    `ack-error`: Acknowledge an error by ID
20
21
22
    """
23
24
    def __init__(self, bot):
25
        self.bot = bot
26
27
    @commands.command(name="ack-error", help="Acknowledge an error to stop it from appearing")
28
    @commands.check(utils.check_admin)
29
    async def ack_error(self, ctx: commands.Context, error_id: str) -> None:
30
        """Ack Error
31
32
        Acknowledge an error to prevent it from appearing in the task
33
34
        :param ctx: Command context
35
        :type ctx: discord.ext.commands.Context
36
        :param error_id: ID of the error
37
        :type error_id: str
38
        :return: None
39
        """
40
        error = await utils.select("errors", "id", "id", error_id)
41
        if not error:
42
            await ctx.send(f"Error {error_id} not found")
43
        else:
44
            await utils.update(
45
                table="errors",
46
                where_column="id",
47
                where_value=error_id,
48
                column="ack",
49
                new_value=True,
50
            )
51
            await ctx.send(f"Error {error_id} has been acknowledged")
52
53
    @commands.command(name="ack-all", help="Acknowledge all errors")
54
    @commands.check(utils.check_admin)
55
    async def ack_all(self, ctx: commands.Context) -> None:
56
        """Ack All
57
58
        Acknowledge all currently unacknowledged errors
59
60
        :param ctx: Command context
61
        :type ctx: discord.ext.commands.Context
62
        :return:  None
63
        """
64
        errors = await utils.select(
65
            table="errors", column="id", where_column="ack", where_value=False
66
        )
67
        if not errors:
68
            await ctx.send("No errors need acknowledging")
69
            return
70
        error_count = 0
71
        for error in errors:
72
            await utils.update(
73
                table="errors",
74
                where_column="id",
75
                where_value=error,
76
                column="ack",
77
                new_value=True,
78
            )
79
            self.bot.log.debug(
80
                f"Acknowledged error {error} as part of bulk acknowledgement"
81
                f" by {ctx.author.display_name}"
82
            )
83
            error_count += 1
84
        await ctx.send(
85
            (
86
                "All errors have been acknowledged.\n"
87
                f"Total: {str(error_count)}\nError Numbers: {', '.join(map(str, errors))}"
88
            )
89
        )
90
91
    @commands.Cog.listener()
92
    async def on_command_error(self, ctx: commands.Context, error: Exception) -> None:
93
        """Error report
94
95
        On error add it to the database and inform user of error
96
97
        :param ctx: Command context
98
        :type ctx: discord.ext.commands.Context
99
        :param error: Error that was raised
100
        :type error: Exception
101
        :return: None
102
        """
103
        if isinstance(error, commands.DisabledCommand):
104
            await cyberjake.error_embed(ctx, message=f"{ctx.command} has been disabled.")
105
            return
106
107
        if isinstance(error, commands.NoPrivateMessage):
108
            try:
109
                await ctx.author.send(f"{ctx.command} can not be used in Private Messages.")
110
                return
111
            except discord.HTTPException:
112
                pass
113
114
        if isinstance(error, (commands.errors.MissingRole, commands.errors.CheckFailure)):
115
            error_msg = "You do not have the correct role for this command."
116
        elif isinstance(error, commands.errors.CommandNotFound):
117
            return
118
        elif isinstance(error, commands.MissingRequiredArgument):
119
            error_msg = f"`{ctx.message.content}` has missing required arguments"
120
        else:
121
            errors = await utils.fetch("errors", "id")
122
            error_id = random.randint(1, 32767)  # nosec
123
            while error_id in errors:
124
                self.bot.log.warning("Error ID had to be regenerated")
125
                error_id = random.randint(1, 32767)  # nosec
126
127
            # self.bot.log.exception(error, exc_info=True)
128
            error_msg = (
129
                "There was an unknown error.\n"
130
                "Please report it for investigation.\n"
131
                f"Error #{error_id}"
132
            )
133
            self.bot.log.error(f"There was the following error: {error}")
134
            error_info = [
135
                error_id,
136
                ctx.message.content,
137
                f"COG: {ctx.command.cog.qualified_name} COMMAND: {ctx.command.name}",
138
                str(error),
139
                datetime.utcnow(),
140
                False,
141
            ]
142
            await utils.insert("errors", error_info)
143
144
        await cyberjake.make_embed(ctx, "FF0000", title="Error:", description=error_msg)
145
146
147
async def setup(bot: commands.Bot) -> None:
148
    """Needed for extension loading"""
149
    await bot.add_cog(ErrorsCog(bot))
150