ruff: Fix N818 exception name should be named with an Error suffix.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2022-11-17 00:30:48 -08:00 committed by Tim Abbott
parent eb2c822d3f
commit 73c4da7974
110 changed files with 507 additions and 507 deletions

View File

@ -8,7 +8,7 @@ from django.utils.timezone import now as timezone_now
from analytics.lib.counts import COUNT_STATS, CountStat from analytics.lib.counts import COUNT_STATS, CountStat
from analytics.models import installation_epoch from analytics.models import installation_epoch
from zerver.lib.timestamp import TimeZoneNotUTCException, floor_to_day, floor_to_hour, verify_UTC from zerver.lib.timestamp import TimeZoneNotUTCError, floor_to_day, floor_to_hour, verify_UTC
from zerver.models import Realm from zerver.models import Realm
states = { states = {
@ -48,7 +48,7 @@ class Command(BaseCommand):
last_fill = installation_epoch() last_fill = installation_epoch()
try: try:
verify_UTC(last_fill) verify_UTC(last_fill)
except TimeZoneNotUTCException: except TimeZoneNotUTCError:
return {"status": 2, "message": f"FillState not in UTC for {property}"} return {"status": 2, "message": f"FillState not in UTC for {property}"}
if stat.frequency == CountStat.DAY: if stat.frequency == CountStat.DAY:

View File

@ -53,7 +53,7 @@ from zerver.actions.users import do_deactivate_user
from zerver.lib.create_user import create_user from zerver.lib.create_user import create_user
from zerver.lib.exceptions import InvitationError from zerver.lib.exceptions import InvitationError
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timestamp import TimeZoneNotUTCException, floor_to_day from zerver.lib.timestamp import TimeZoneNotUTCError, floor_to_day
from zerver.lib.topic import DB_TOPIC_NAME from zerver.lib.topic import DB_TOPIC_NAME
from zerver.lib.utils import assert_is_not_none from zerver.lib.utils import assert_is_not_none
from zerver.models import ( from zerver.models import (
@ -290,7 +290,7 @@ class TestProcessCountStat(AnalyticsTestCase):
stat = self.make_dummy_count_stat("test stat") stat = self.make_dummy_count_stat("test stat")
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
process_count_stat(stat, installation_epoch() + 65 * self.MINUTE) process_count_stat(stat, installation_epoch() + 65 * self.MINUTE)
with self.assertRaises(TimeZoneNotUTCException): with self.assertRaises(TimeZoneNotUTCError):
process_count_stat(stat, installation_epoch().replace(tzinfo=None)) process_count_stat(stat, installation_epoch().replace(tzinfo=None))
# This tests the LoggingCountStat branch of the code in do_delete_counts_at_hour. # This tests the LoggingCountStat branch of the code in do_delete_counts_at_hour.

View File

@ -29,7 +29,7 @@ from zerver.models import (
) )
class ConfirmationKeyException(Exception): class ConfirmationKeyError(Exception):
WRONG_LENGTH = 1 WRONG_LENGTH = 1
EXPIRED = 2 EXPIRED = 2
DOES_NOT_EXIST = 3 DOES_NOT_EXIST = 3
@ -40,11 +40,11 @@ class ConfirmationKeyException(Exception):
def render_confirmation_key_error( def render_confirmation_key_error(
request: HttpRequest, exception: ConfirmationKeyException request: HttpRequest, exception: ConfirmationKeyError
) -> HttpResponse: ) -> HttpResponse:
if exception.error_type == ConfirmationKeyException.WRONG_LENGTH: if exception.error_type == ConfirmationKeyError.WRONG_LENGTH:
return render(request, "confirmation/link_malformed.html", status=404) return render(request, "confirmation/link_malformed.html", status=404)
if exception.error_type == ConfirmationKeyException.EXPIRED: if exception.error_type == ConfirmationKeyError.EXPIRED:
return render(request, "confirmation/link_expired.html", status=404) return render(request, "confirmation/link_expired.html", status=404)
return render(request, "confirmation/link_does_not_exist.html", status=404) return render(request, "confirmation/link_does_not_exist.html", status=404)
@ -77,16 +77,16 @@ def get_object_from_key(
# Confirmation keys used to be 40 characters # Confirmation keys used to be 40 characters
if len(confirmation_key) not in (24, 40): if len(confirmation_key) not in (24, 40):
raise ConfirmationKeyException(ConfirmationKeyException.WRONG_LENGTH) raise ConfirmationKeyError(ConfirmationKeyError.WRONG_LENGTH)
try: try:
confirmation = Confirmation.objects.get( confirmation = Confirmation.objects.get(
confirmation_key=confirmation_key, type__in=confirmation_types confirmation_key=confirmation_key, type__in=confirmation_types
) )
except Confirmation.DoesNotExist: except Confirmation.DoesNotExist:
raise ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST) raise ConfirmationKeyError(ConfirmationKeyError.DOES_NOT_EXIST)
if confirmation.expiry_date is not None and timezone_now() > confirmation.expiry_date: if confirmation.expiry_date is not None and timezone_now() > confirmation.expiry_date:
raise ConfirmationKeyException(ConfirmationKeyException.EXPIRED) raise ConfirmationKeyError(ConfirmationKeyError.EXPIRED)
obj = confirmation.content_object obj = confirmation.content_object
assert obj is not None assert obj is not None
@ -96,7 +96,7 @@ def get_object_from_key(
if hasattr(obj, "status") and obj.status in [used_value, revoked_value]: if hasattr(obj, "status") and obj.status in [used_value, revoked_value]:
# Confirmations where the object has the status attribute are one-time use # Confirmations where the object has the status attribute are one-time use
# and are marked after being used (or revoked). # and are marked after being used (or revoked).
raise ConfirmationKeyException(ConfirmationKeyException.EXPIRED) raise ConfirmationKeyError(ConfirmationKeyError.EXPIRED)
if mark_object_used: if mark_object_used:
# MultiuseInvite objects do not use the STATUS_USED status, since they are # MultiuseInvite objects do not use the STATUS_USED status, since they are
@ -240,10 +240,10 @@ def validate_key(creation_key: Optional[str]) -> Optional["RealmCreationKey"]:
try: try:
key_record = RealmCreationKey.objects.get(creation_key=creation_key) key_record = RealmCreationKey.objects.get(creation_key=creation_key)
except RealmCreationKey.DoesNotExist: except RealmCreationKey.DoesNotExist:
raise RealmCreationKey.Invalid() raise RealmCreationKey.InvalidError()
time_elapsed = timezone_now() - key_record.date_created time_elapsed = timezone_now() - key_record.date_created
if time_elapsed.total_seconds() > settings.REALM_CREATION_LINK_VALIDITY_DAYS * 24 * 3600: if time_elapsed.total_seconds() > settings.REALM_CREATION_LINK_VALIDITY_DAYS * 24 * 3600:
raise RealmCreationKey.Invalid() raise RealmCreationKey.InvalidError()
return key_record return key_record
@ -266,5 +266,5 @@ class RealmCreationKey(models.Model):
# is theirs, and skip sending mail to it to confirm that. # is theirs, and skip sending mail to it to confirm that.
presume_email_valid = models.BooleanField(default=False) presume_email_valid = models.BooleanField(default=False)
class Invalid(Exception): class InvalidError(Exception):
pass pass

View File

@ -248,13 +248,13 @@ class UpgradeWithExistingPlanError(BillingError):
) )
class InvalidBillingSchedule(Exception): class InvalidBillingScheduleError(Exception):
def __init__(self, billing_schedule: int) -> None: def __init__(self, billing_schedule: int) -> None:
self.message = f"Unknown billing_schedule: {billing_schedule}" self.message = f"Unknown billing_schedule: {billing_schedule}"
super().__init__(self.message) super().__init__(self.message)
class InvalidTier(Exception): class InvalidTierError(Exception):
def __init__(self, tier: int) -> None: def __init__(self, tier: int) -> None:
self.message = f"Unknown tier: {tier}" self.message = f"Unknown tier: {tier}"
super().__init__(self.message) super().__init__(self.message)
@ -570,16 +570,16 @@ def get_price_per_license(
elif billing_schedule == CustomerPlan.MONTHLY: elif billing_schedule == CustomerPlan.MONTHLY:
price_per_license = 800 price_per_license = 800
else: # nocoverage else: # nocoverage
raise InvalidBillingSchedule(billing_schedule) raise InvalidBillingScheduleError(billing_schedule)
elif tier == CustomerPlan.PLUS: elif tier == CustomerPlan.PLUS:
if billing_schedule == CustomerPlan.ANNUAL: if billing_schedule == CustomerPlan.ANNUAL:
price_per_license = 16000 price_per_license = 16000
elif billing_schedule == CustomerPlan.MONTHLY: elif billing_schedule == CustomerPlan.MONTHLY:
price_per_license = 1600 price_per_license = 1600
else: # nocoverage else: # nocoverage
raise InvalidBillingSchedule(billing_schedule) raise InvalidBillingScheduleError(billing_schedule)
else: else:
raise InvalidTier(tier) raise InvalidTierError(tier)
if discount is not None: if discount is not None:
price_per_license = calculate_discounted_price_per_license(price_per_license, discount) price_per_license = calculate_discounted_price_per_license(price_per_license, discount)
@ -602,7 +602,7 @@ def compute_plan_parameters(
elif billing_schedule == CustomerPlan.MONTHLY: elif billing_schedule == CustomerPlan.MONTHLY:
period_end = add_months(billing_cycle_anchor, 1) period_end = add_months(billing_cycle_anchor, 1)
else: # nocoverage else: # nocoverage
raise InvalidBillingSchedule(billing_schedule) raise InvalidBillingScheduleError(billing_schedule)
price_per_license = get_price_per_license(tier, billing_schedule, discount) price_per_license = get_price_per_license(tier, billing_schedule, discount)

View File

@ -40,8 +40,8 @@ from corporate.lib.stripe import (
MIN_INVOICED_LICENSES, MIN_INVOICED_LICENSES,
STRIPE_API_VERSION, STRIPE_API_VERSION,
BillingError, BillingError,
InvalidBillingSchedule, InvalidBillingScheduleError,
InvalidTier, InvalidTierError,
StripeCardError, StripeCardError,
add_months, add_months,
approve_sponsorship, approve_sponsorship,
@ -4302,10 +4302,10 @@ class BillingHelpersTest(ZulipTestCase):
800, 800,
) )
with self.assertRaisesRegex(InvalidBillingSchedule, "Unknown billing_schedule: 1000"): with self.assertRaisesRegex(InvalidBillingScheduleError, "Unknown billing_schedule: 1000"):
get_price_per_license(CustomerPlan.STANDARD, 1000) get_price_per_license(CustomerPlan.STANDARD, 1000)
with self.assertRaisesRegex(InvalidTier, "Unknown tier: 10"): with self.assertRaisesRegex(InvalidTierError, "Unknown tier: 10"):
get_price_per_license(CustomerPlan.ENTERPRISE, CustomerPlan.ANNUAL) get_price_per_license(CustomerPlan.ENTERPRISE, CustomerPlan.ANNUAL)
def test_get_plan_renewal_or_end_date(self) -> None: def test_get_plan_renewal_or_end_date(self) -> None:

View File

@ -9,7 +9,10 @@ from django.template.response import TemplateResponse
from zerver.context_processors import get_realm_from_request, latest_info_context from zerver.context_processors import get_realm_from_request, latest_info_context
from zerver.decorator import add_google_analytics from zerver.decorator import add_google_analytics
from zerver.lib.github import InvalidPlatform, get_latest_github_release_download_link_for_platform from zerver.lib.github import (
InvalidPlatformError,
get_latest_github_release_download_link_for_platform,
)
from zerver.lib.realm_description import get_realm_text_description from zerver.lib.realm_description import get_realm_text_description
from zerver.lib.realm_icon import get_realm_icon_url from zerver.lib.realm_icon import get_realm_icon_url
from zerver.lib.subdomains import is_subdomain_root_or_alias from zerver.lib.subdomains import is_subdomain_root_or_alias
@ -30,7 +33,7 @@ def app_download_link_redirect(request: HttpRequest, platform: str) -> HttpRespo
try: try:
download_link = get_latest_github_release_download_link_for_platform(platform) download_link = get_latest_github_release_download_link_for_platform(platform)
return HttpResponseRedirect(download_link, status=302) return HttpResponseRedirect(download_link, status=302)
except InvalidPlatform: except InvalidPlatformError:
return TemplateResponse(request, "404.html", status=404) return TemplateResponse(request, "404.html", status=404)

View File

@ -125,7 +125,6 @@ ignore = [
"E731", # Do not assign a lambda expression, use a def "E731", # Do not assign a lambda expression, use a def
"N802", # Function name should be lowercase "N802", # Function name should be lowercase
"N806", # Variable in function should be lowercase "N806", # Variable in function should be lowercase
"N818", # Exception name should be named with an Error suffix
] ]
line-length = 100 line-length = 100
src = [".", "tools", "tools/setup/emoji"] src = [".", "tools", "tools/setup/emoji"]

View File

@ -628,9 +628,9 @@ Many third-party services have dozens of different event types. In
some cases, we may choose to explicitly ignore specific events. In some cases, we may choose to explicitly ignore specific events. In
other cases, there may be events that are new or events that we don't other cases, there may be events that are new or events that we don't
know about. In such cases, we recommend raising know about. In such cases, we recommend raising
`UnsupportedWebhookEventType` (found in `zerver/lib/exceptions.py`), `UnsupportedWebhookEventTypeError` (found in `zerver/lib/exceptions.py`),
with a string describing the unsupported event type, like so: with a string describing the unsupported event type, like so:
``` ```
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
``` ```

View File

@ -12,7 +12,7 @@ exclude_lines =
# Don't require coverage for __str__ statements just used for printing # Don't require coverage for __str__ statements just used for printing
def __str__[(]self[)] -> .*: def __str__[(]self[)] -> .*:
# Don't require coverage for errors about unsupported webhook event types # Don't require coverage for errors about unsupported webhook event types
raise UnsupportedWebhookEventType raise UnsupportedWebhookEventTypeError
# Don't require coverage for blocks only run when type-checking # Don't require coverage for blocks only run when type-checking
if TYPE_CHECKING: if TYPE_CHECKING:
# Don't require coverage for abstract methods; they're never called. # Don't require coverage for abstract methods; they're never called.

View File

@ -2,7 +2,7 @@ import re
from collections import defaultdict from collections import defaultdict
from typing import Dict, List from typing import Dict, List
from .template_parser import FormattedException, Token, tokenize from .template_parser import FormattedError, Token, tokenize
class TagInfo: class TagInfo:
@ -83,7 +83,7 @@ def build_id_dict(templates: List[str]) -> (Dict[str, List[str]]):
try: try:
list_tags = tokenize(text) list_tags = tokenize(text)
except FormattedException as e: except FormattedError as e:
raise Exception( raise Exception(
f""" f"""
fn: {fn} fn: {fn}

View File

@ -1,11 +1,11 @@
from typing import Callable, List, Optional from typing import Callable, List, Optional
class FormattedException(Exception): class FormattedError(Exception):
pass pass
class TemplateParserException(Exception): class TemplateParserError(Exception):
def __init__(self, message: str) -> None: def __init__(self, message: str) -> None:
self.message = message self.message = message
@ -13,7 +13,7 @@ class TemplateParserException(Exception):
return self.message return self.message
class TokenizationException(Exception): class TokenizationError(Exception):
def __init__(self, message: str, line_content: Optional[str] = None) -> None: def __init__(self, message: str, line_content: Optional[str] = None) -> None:
self.message = message self.message = message
self.line_content = line_content self.line_content = line_content
@ -149,7 +149,7 @@ def tokenize(text: str) -> List[Token]:
tag_parts = s[1:end_offset].split() tag_parts = s[1:end_offset].split()
if not tag_parts: if not tag_parts:
raise TemplateParserException("Tag name missing") raise TemplateParserError("Tag name missing")
tag = tag_parts[0] tag = tag_parts[0]
@ -228,8 +228,8 @@ def tokenize(text: str) -> List[Token]:
continue continue
tag = "" tag = ""
kind = "text" kind = "text"
except TokenizationException as e: except TokenizationError as e:
raise FormattedException( raise FormattedError(
f'''{e.message} at line {state.line} col {state.col}:"{e.line_content}"''', f'''{e.message} at line {state.line} col {state.col}:"{e.line_content}"''',
) )
@ -350,8 +350,8 @@ def validate(fn: Optional[str] = None, text: Optional[str] = None) -> List[Token
try: try:
tokens = tokenize(text) tokens = tokenize(text)
except FormattedException as e: except FormattedError as e:
raise TemplateParserException( raise TemplateParserError(
f""" f"""
fn: {fn} fn: {fn}
{e}""" {e}"""
@ -367,7 +367,7 @@ def validate(fn: Optional[str] = None, text: Optional[str] = None) -> List[Token
def no_start_tag(token: Optional[Token]) -> None: def no_start_tag(token: Optional[Token]) -> None:
assert token assert token
raise TemplateParserException( raise TemplateParserError(
f""" f"""
No start tag No start tag
fn: {fn} fn: {fn}
@ -393,7 +393,7 @@ def validate(fn: Optional[str] = None, text: Optional[str] = None) -> List[Token
def f(end_token: Optional[Token]) -> None: def f(end_token: Optional[Token]) -> None:
if end_token is None: if end_token is None:
raise TemplateParserException( raise TemplateParserError(
f""" f"""
Problem with {fn} Problem with {fn}
@ -429,7 +429,7 @@ def validate(fn: Optional[str] = None, text: Optional[str] = None) -> List[Token
problem = report_problem() problem = report_problem()
if problem: if problem:
raise TemplateParserException( raise TemplateParserError(
f""" f"""
fn: {fn} fn: {fn}
{problem} {problem}
@ -460,12 +460,12 @@ def validate(fn: Optional[str] = None, text: Optional[str] = None) -> List[Token
if not state.foreign: if not state.foreign:
if kind == "html_start": if kind == "html_start":
if tag in HTML_VOID_TAGS: if tag in HTML_VOID_TAGS:
raise TemplateParserException( raise TemplateParserError(
f"Tag must be self-closing: {tag} at {fn} line {token.line}, col {token.col}" f"Tag must be self-closing: {tag} at {fn} line {token.line}, col {token.col}"
) )
elif kind == "html_singleton": elif kind == "html_singleton":
if tag not in HTML_VOID_TAGS: if tag not in HTML_VOID_TAGS:
raise TemplateParserException( raise TemplateParserError(
f"Tag must not be self-closing: {tag} at {fn} line {token.line}, col {token.col}" f"Tag must not be self-closing: {tag} at {fn} line {token.line}, col {token.col}"
) )
@ -514,7 +514,7 @@ def ensure_matching_indentation(fn: str, tokens: List[Token], lines: List[str])
return False return False
if has_bad_indentation(): if has_bad_indentation():
raise TemplateParserException( raise TemplateParserError(
f""" f"""
fn: {fn} fn: {fn}
Indentation for start/end tags does not match. Indentation for start/end tags does not match.
@ -539,14 +539,14 @@ def prevent_extra_newlines(fn: str, tokens: List[Token]) -> None:
count += 1 count += 1
if count >= 4: if count >= 4:
raise TemplateParserException( raise TemplateParserError(
f"""Please avoid so many blank lines near row {token.line} in {fn}.""" f"""Please avoid so many blank lines near row {token.line} in {fn}."""
) )
def prevent_whitespace_violations(fn: str, tokens: List[Token]) -> None: def prevent_whitespace_violations(fn: str, tokens: List[Token]) -> None:
if tokens[0].kind in ("indent", "whitespace"): if tokens[0].kind in ("indent", "whitespace"):
raise TemplateParserException(f" Please remove the whitespace at the beginning of {fn}.") raise TemplateParserError(f" Please remove the whitespace at the beginning of {fn}.")
prevent_extra_newlines(fn, tokens) prevent_extra_newlines(fn, tokens)
@ -559,12 +559,12 @@ def prevent_whitespace_violations(fn: str, tokens: List[Token]) -> None:
raise AssertionError("programming error parsing indents") raise AssertionError("programming error parsing indents")
if next_token.kind == "newline": if next_token.kind == "newline":
raise TemplateParserException( raise TemplateParserError(
f"""Please just make row {token.line} in {fn} a truly blank line (no spaces).""" f"""Please just make row {token.line} in {fn} a truly blank line (no spaces)."""
) )
if len(token.s) % 4 != 0: if len(token.s) % 4 != 0:
raise TemplateParserException( raise TemplateParserError(
f""" f"""
Please use 4-space indents for template files. Most of our Please use 4-space indents for template files. Most of our
codebase (including Python and JavaScript) uses 4-space indents, codebase (including Python and JavaScript) uses 4-space indents,
@ -578,13 +578,13 @@ def prevent_whitespace_violations(fn: str, tokens: List[Token]) -> None:
if token.kind == "whitespace": if token.kind == "whitespace":
if len(token.s) > 1: if len(token.s) > 1:
raise TemplateParserException( raise TemplateParserError(
f""" f"""
We did not expect this much whitespace at row {token.line} column {token.col} in {fn}. We did not expect this much whitespace at row {token.line} column {token.col} in {fn}.
""" """
) )
if next_token.kind == "newline": if next_token.kind == "newline":
raise TemplateParserException( raise TemplateParserError(
f""" f"""
Unexpected trailing whitespace at row {token.line} column {token.col} in {fn}. Unexpected trailing whitespace at row {token.line} column {token.col} in {fn}.
""" """
@ -613,7 +613,7 @@ def get_handlebars_tag(text: str, i: int) -> str:
while end < len(text) - 1 and text[end] != "}": while end < len(text) - 1 and text[end] != "}":
end += 1 end += 1
if text[end] != "}" or text[end + 1] != "}": if text[end] != "}" or text[end + 1] != "}":
raise TokenizationException('Tag missing "}}"', text[i : end + 2]) raise TokenizationError('Tag missing "}}"', text[i : end + 2])
s = text[i : end + 2] s = text[i : end + 2]
return s return s
@ -649,7 +649,7 @@ def get_django_tag(text: str, i: int, stripped: bool = False) -> str:
while end < len(text) - 1 and text[end] != "%": while end < len(text) - 1 and text[end] != "%":
end += 1 end += 1
if text[end] != "%" or text[end + 1] != "}": if text[end] != "%" or text[end + 1] != "}":
raise TokenizationException('Tag missing "%}"', text[i : end + 2]) raise TokenizationError('Tag missing "%}"', text[i : end + 2])
s = text[i : end + 2] s = text[i : end + 2]
return s return s
@ -666,11 +666,11 @@ def get_html_tag(text: str, i: int) -> str:
end += 1 end += 1
if quote_count % 2 != 0: if quote_count % 2 != 0:
if unclosed_end: if unclosed_end:
raise TokenizationException("Unbalanced quotes", text[i:unclosed_end]) raise TokenizationError("Unbalanced quotes", text[i:unclosed_end])
else: else:
raise TokenizationException("Unbalanced quotes", text[i : end + 1]) raise TokenizationError("Unbalanced quotes", text[i : end + 1])
if end == len(text) or text[end] != ">": if end == len(text) or text[end] != ">":
raise TokenizationException('Tag missing ">"', text[i : end + 1]) raise TokenizationError('Tag missing ">"', text[i : end + 1])
s = text[i : end + 1] s = text[i : end + 1]
return s return s
@ -684,7 +684,7 @@ def get_html_comment(text: str, i: int) -> str:
if not unclosed_end and text[end] == "<": if not unclosed_end and text[end] == "<":
unclosed_end = end unclosed_end = end
end += 1 end += 1
raise TokenizationException("Unclosed comment", text[i:unclosed_end]) raise TokenizationError("Unclosed comment", text[i:unclosed_end])
def get_handlebars_comment(text: str, i: int) -> str: def get_handlebars_comment(text: str, i: int) -> str:
@ -696,7 +696,7 @@ def get_handlebars_comment(text: str, i: int) -> str:
if not unclosed_end and text[end] == "<": if not unclosed_end and text[end] == "<":
unclosed_end = end unclosed_end = end
end += 1 end += 1
raise TokenizationException("Unclosed comment", text[i:unclosed_end]) raise TokenizationError("Unclosed comment", text[i:unclosed_end])
def get_template_var(text: str, i: int) -> str: def get_template_var(text: str, i: int) -> str:
@ -710,7 +710,7 @@ def get_template_var(text: str, i: int) -> str:
if not unclosed_end and text[end] == "<": if not unclosed_end and text[end] == "<":
unclosed_end = end unclosed_end = end
end += 1 end += 1
raise TokenizationException("Unclosed var", text[i:unclosed_end]) raise TokenizationError("Unclosed var", text[i:unclosed_end])
def get_django_comment(text: str, i: int) -> str: def get_django_comment(text: str, i: int) -> str:
@ -722,7 +722,7 @@ def get_django_comment(text: str, i: int) -> str:
if not unclosed_end and text[end] == "<": if not unclosed_end and text[end] == "<":
unclosed_end = end unclosed_end = end
end += 1 end += 1
raise TokenizationException("Unclosed comment", text[i:unclosed_end]) raise TokenizationError("Unclosed comment", text[i:unclosed_end])
def get_handlebars_partial(text: str, i: int) -> str: def get_handlebars_partial(text: str, i: int) -> str:
@ -734,4 +734,4 @@ def get_handlebars_partial(text: str, i: int) -> str:
if not unclosed_end and text[end] == "<": if not unclosed_end and text[end] == "<":
unclosed_end = end unclosed_end = end
end += 1 end += 1
raise TokenizationException("Unclosed partial", text[i:unclosed_end]) raise TokenizationError("Unclosed partial", text[i:unclosed_end])

View File

@ -4,7 +4,7 @@ from typing import Optional
try: try:
from tools.lib.template_parser import ( from tools.lib.template_parser import (
TemplateParserException, TemplateParserError,
is_django_block_tag, is_django_block_tag,
tokenize, tokenize,
validate, validate,
@ -21,7 +21,7 @@ class ParserTest(unittest.TestCase):
fn: Optional[str] = None, fn: Optional[str] = None,
text: Optional[str] = None, text: Optional[str] = None,
) -> None: ) -> None:
with self.assertRaisesRegex(TemplateParserException, error): with self.assertRaisesRegex(TemplateParserError, error):
validate(fn=fn, text=text) validate(fn=fn, text=text)
def test_is_django_block_tag(self) -> None: def test_is_django_block_tag(self) -> None:

View File

@ -35,10 +35,10 @@ from zerver.lib.cache import cache_with_key, user_profile_delivery_email_cache_k
from zerver.lib.create_user import create_user from zerver.lib.create_user import create_user
from zerver.lib.exceptions import ( from zerver.lib.exceptions import (
JsonableError, JsonableError,
MarkdownRenderingException, MarkdownRenderingError,
StreamDoesNotExistError, StreamDoesNotExistError,
StreamWithIDDoesNotExistError, StreamWithIDDoesNotExistError,
ZephyrMessageAlreadySentException, ZephyrMessageAlreadySentError,
) )
from zerver.lib.markdown import MessageRenderingResult from zerver.lib.markdown import MessageRenderingResult
from zerver.lib.markdown import version as markdown_version from zerver.lib.markdown import version as markdown_version
@ -148,7 +148,7 @@ def render_incoming_message(
url_embed_data=url_embed_data, url_embed_data=url_embed_data,
email_gateway=email_gateway, email_gateway=email_gateway,
) )
except MarkdownRenderingException: except MarkdownRenderingError:
raise JsonableError(_("Unable to render message")) raise JsonableError(_("Unable to render message"))
return rendering_result return rendering_result
@ -1173,7 +1173,7 @@ def check_send_message(
widget_content, widget_content,
skip_stream_access_check=skip_stream_access_check, skip_stream_access_check=skip_stream_access_check,
) )
except ZephyrMessageAlreadySentException as e: except ZephyrMessageAlreadySentError as e:
return e.message_id return e.message_id
return do_send_messages([message])[0] return do_send_messages([message])[0]
@ -1460,7 +1460,7 @@ def check_message(
if client.name == "zephyr_mirror": if client.name == "zephyr_mirror":
id = already_sent_mirrored_message_id(message) id = already_sent_mirrored_message_id(message)
if id is not None: if id is not None:
raise ZephyrMessageAlreadySentException(id) raise ZephyrMessageAlreadySentError(id)
widget_content_dict = None widget_content_dict = None
if widget_content is not None: if widget_content is not None:

View File

@ -38,17 +38,17 @@ from typing_extensions import Concatenate, ParamSpec
from zerver.lib.exceptions import ( from zerver.lib.exceptions import (
AccessDeniedError, AccessDeniedError,
AnomalousWebhookPayload, AnomalousWebhookPayloadError,
InvalidAPIKeyError, InvalidAPIKeyError,
InvalidAPIKeyFormatError, InvalidAPIKeyFormatError,
InvalidJSONError, InvalidJSONError,
JsonableError, JsonableError,
OrganizationAdministratorRequired, OrganizationAdministratorRequiredError,
OrganizationMemberRequired, OrganizationMemberRequiredError,
OrganizationOwnerRequired, OrganizationOwnerRequiredError,
RealmDeactivatedError, RealmDeactivatedError,
UnauthorizedError, UnauthorizedError,
UnsupportedWebhookEventType, UnsupportedWebhookEventTypeError,
UserDeactivatedError, UserDeactivatedError,
WebhookError, WebhookError,
) )
@ -139,7 +139,7 @@ def require_realm_owner(
**kwargs: ParamT.kwargs, **kwargs: ParamT.kwargs,
) -> HttpResponse: ) -> HttpResponse:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
return func(request, user_profile, *args, **kwargs) return func(request, user_profile, *args, **kwargs)
return wrapper return wrapper
@ -157,7 +157,7 @@ def require_realm_admin(
**kwargs: ParamT.kwargs, **kwargs: ParamT.kwargs,
) -> HttpResponse: ) -> HttpResponse:
if not user_profile.is_realm_admin: if not user_profile.is_realm_admin:
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
return func(request, user_profile, *args, **kwargs) return func(request, user_profile, *args, **kwargs)
return wrapper return wrapper
@ -175,7 +175,7 @@ def require_organization_member(
**kwargs: ParamT.kwargs, **kwargs: ParamT.kwargs,
) -> HttpResponse: ) -> HttpResponse:
if user_profile.role > UserProfile.ROLE_MEMBER: if user_profile.role > UserProfile.ROLE_MEMBER:
raise OrganizationMemberRequired() raise OrganizationMemberRequiredError()
return func(request, user_profile, *args, **kwargs) return func(request, user_profile, *args, **kwargs)
return wrapper return wrapper
@ -303,15 +303,15 @@ def log_unsupported_webhook_event(summary: str) -> None:
# webhook integrations (e.g. GitHub) that need to log an unsupported # webhook integrations (e.g. GitHub) that need to log an unsupported
# event based on attributes nested deep within a complicated JSON # event based on attributes nested deep within a complicated JSON
# payload. In such cases, the error message we want to log may not # payload. In such cases, the error message we want to log may not
# really fit what a regular UnsupportedWebhookEventType exception # really fit what a regular UnsupportedWebhookEventTypeError exception
# represents. # represents.
webhook_unsupported_events_logger.exception(summary, stack_info=True) webhook_unsupported_events_logger.exception(summary, stack_info=True)
def log_exception_to_webhook_logger(err: Exception) -> None: def log_exception_to_webhook_logger(err: Exception) -> None:
if isinstance(err, AnomalousWebhookPayload): if isinstance(err, AnomalousWebhookPayloadError):
webhook_anomalous_payloads_logger.exception(str(err), stack_info=True) webhook_anomalous_payloads_logger.exception(str(err), stack_info=True)
elif isinstance(err, UnsupportedWebhookEventType): elif isinstance(err, UnsupportedWebhookEventTypeError):
webhook_unsupported_events_logger.exception(str(err), stack_info=True) webhook_unsupported_events_logger.exception(str(err), stack_info=True)
else: else:
webhook_logger.exception(str(err), stack_info=True) webhook_logger.exception(str(err), stack_info=True)

View File

@ -26,7 +26,7 @@ from zerver.lib.email_validation import (
email_allowed_for_realm, email_allowed_for_realm,
email_reserved_for_system_bots_error, email_reserved_for_system_bots_error,
) )
from zerver.lib.exceptions import JsonableError, RateLimited from zerver.lib.exceptions import JsonableError, RateLimitedError
from zerver.lib.name_restrictions import is_disposable_domain, is_reserved_subdomain from zerver.lib.name_restrictions import is_disposable_domain, is_reserved_subdomain
from zerver.lib.rate_limiter import RateLimitedObject, rate_limit_request_by_ip from zerver.lib.rate_limiter import RateLimitedObject, rate_limit_request_by_ip
from zerver.lib.send_email import FromAddress, send_email from zerver.lib.send_email import FromAddress, send_email
@ -344,7 +344,7 @@ class ZulipPasswordResetForm(PasswordResetForm):
try: try:
rate_limit_password_reset_form_by_email(email) rate_limit_password_reset_form_by_email(email)
rate_limit_request_by_ip(request, domain="sends_email_by_ip") rate_limit_request_by_ip(request, domain="sends_email_by_ip")
except RateLimited: except RateLimitedError:
logging.info( logging.info(
"Too many password reset attempts for email %s from %s", "Too many password reset attempts for email %s from %s",
email, email,
@ -418,7 +418,7 @@ class RateLimitedPasswordResetByEmail(RateLimitedObject):
def rate_limit_password_reset_form_by_email(email: str) -> None: def rate_limit_password_reset_form_by_email(email: str) -> None:
ratelimited, secs_to_freedom = RateLimitedPasswordResetByEmail(email).rate_limit() ratelimited, secs_to_freedom = RateLimitedPasswordResetByEmail(email).rate_limit()
if ratelimited: if ratelimited:
raise RateLimited(secs_to_freedom) raise RateLimitedError(secs_to_freedom)
class CreateUserForm(forms.Form): class CreateUserForm(forms.Form):
@ -447,7 +447,7 @@ class OurAuthenticationForm(AuthenticationForm):
realm=realm, realm=realm,
return_data=return_data, return_data=return_data,
) )
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
secs_to_freedom = int(e.secs_to_freedom) secs_to_freedom = int(e.secs_to_freedom)
error_message = _( error_message = _(

View File

@ -58,11 +58,11 @@ class StateHandler:
return is_key_in_bot_storage(self.user_profile, key) return is_key_in_bot_storage(self.user_profile, key)
class EmbeddedBotQuitException(Exception): class EmbeddedBotQuitError(Exception):
pass pass
class EmbeddedBotEmptyRecipientsList(Exception): class EmbeddedBotEmptyRecipientsListError(Exception):
pass pass
@ -102,7 +102,7 @@ class EmbeddedBotHandler:
recipients = ",".join(message["to"]).split(",") recipients = ",".join(message["to"]).split(",")
if len(message["to"]) == 0: if len(message["to"]) == 0:
raise EmbeddedBotEmptyRecipientsList(_("Message must have recipients!")) raise EmbeddedBotEmptyRecipientsListError(_("Message must have recipients!"))
elif len(message["to"]) == 1: elif len(message["to"]) == 1:
recipient_user = get_active_user(recipients[0], self.user_profile.realm) recipient_user = get_active_user(recipients[0], self.user_profile.realm)
message_id = internal_send_private_message( message_id = internal_send_private_message(
@ -151,4 +151,4 @@ class EmbeddedBotHandler:
raise raise
def quit(self, message: str = "") -> None: def quit(self, message: str = "") -> None:
raise EmbeddedBotQuitException(message) raise EmbeddedBotQuitError(message)

View File

@ -44,11 +44,6 @@ ReturnT = TypeVar("ReturnT")
logger = logging.getLogger() logger = logging.getLogger()
class NotFoundInCache(Exception):
pass
remote_cache_time_start = 0.0 remote_cache_time_start = 0.0
remote_cache_total_time = 0.0 remote_cache_total_time = 0.0
remote_cache_total_requests = 0 remote_cache_total_requests = 0
@ -151,7 +146,7 @@ def cache_with_key(
try: try:
val = cache_get(key, cache_name=cache_name) val = cache_get(key, cache_name=cache_name)
except InvalidCacheKeyException: except InvalidCacheKeyError:
stack_trace = traceback.format_exc() stack_trace = traceback.format_exc()
log_invalid_cache_keys(stack_trace, [key]) log_invalid_cache_keys(stack_trace, [key])
return func(*args, **kwargs) return func(*args, **kwargs)
@ -190,7 +185,7 @@ def cache_with_key(
return decorator return decorator
class InvalidCacheKeyException(Exception): class InvalidCacheKeyError(Exception):
pass pass
@ -215,9 +210,9 @@ def validate_cache_key(key: str) -> None:
# The regex checks "all characters between ! and ~ in the ascii table", # The regex checks "all characters between ! and ~ in the ascii table",
# which happens to be the set of all "nice" ascii characters. # which happens to be the set of all "nice" ascii characters.
if not bool(re.fullmatch(r"([!-~])+", key)): if not bool(re.fullmatch(r"([!-~])+", key)):
raise InvalidCacheKeyException("Invalid characters in the cache key: " + key) raise InvalidCacheKeyError("Invalid characters in the cache key: " + key)
if len(key) > MEMCACHED_MAX_KEY_LENGTH: if len(key) > MEMCACHED_MAX_KEY_LENGTH:
raise InvalidCacheKeyException(f"Cache key too long: {key} Length: {len(key)}") raise InvalidCacheKeyError(f"Cache key too long: {key} Length: {len(key)}")
def cache_set( def cache_set(
@ -262,7 +257,7 @@ def safe_cache_get_many(keys: List[str], cache_name: Optional[str] = None) -> Di
# to do normal cache_get_many to avoid the overhead of # to do normal cache_get_many to avoid the overhead of
# validating all the keys here. # validating all the keys here.
return cache_get_many(keys, cache_name) return cache_get_many(keys, cache_name)
except InvalidCacheKeyException: except InvalidCacheKeyError:
stack_trace = traceback.format_exc() stack_trace = traceback.format_exc()
good_keys, bad_keys = filter_good_and_bad_keys(keys) good_keys, bad_keys = filter_good_and_bad_keys(keys)
@ -295,7 +290,7 @@ def safe_cache_set_many(
# to do normal cache_set_many to avoid the overhead of # to do normal cache_set_many to avoid the overhead of
# validating all the keys here. # validating all the keys here.
return cache_set_many(items, cache_name, timeout) return cache_set_many(items, cache_name, timeout)
except InvalidCacheKeyException: except InvalidCacheKeyError:
stack_trace = traceback.format_exc() stack_trace = traceback.format_exc()
good_keys, bad_keys = filter_good_and_bad_keys(list(items.keys())) good_keys, bad_keys = filter_good_and_bad_keys(list(items.keys()))
@ -330,7 +325,7 @@ def filter_good_and_bad_keys(keys: List[str]) -> Tuple[List[str], List[str]]:
try: try:
validate_cache_key(key) validate_cache_key(key)
good_keys.append(key) good_keys.append(key)
except InvalidCacheKeyException: except InvalidCacheKeyError:
bad_keys.append(key) bad_keys.append(key)
return good_keys, bad_keys return good_keys, bad_keys

View File

@ -20,7 +20,7 @@ from zerver.lib.email_mirror_helpers import (
get_email_gateway_message_string_from_address, get_email_gateway_message_string_from_address,
) )
from zerver.lib.email_notifications import convert_html_to_markdown from zerver.lib.email_notifications import convert_html_to_markdown
from zerver.lib.exceptions import JsonableError, RateLimited from zerver.lib.exceptions import JsonableError, RateLimitedError
from zerver.lib.message import normalize_body, truncate_topic from zerver.lib.message import normalize_body, truncate_topic
from zerver.lib.queue import queue_json_publish from zerver.lib.queue import queue_json_publish
from zerver.lib.rate_limiter import RateLimitedObject from zerver.lib.rate_limiter import RateLimitedObject
@ -534,4 +534,4 @@ def rate_limit_mirror_by_realm(recipient_realm: Realm) -> None:
ratelimited, secs_to_freedom = RateLimitedRealmMirror(recipient_realm).rate_limit() ratelimited, secs_to_freedom = RateLimitedRealmMirror(recipient_realm).rate_limit()
if ratelimited: if ratelimited:
raise RateLimited(secs_to_freedom) raise RateLimitedError(secs_to_freedom)

View File

@ -76,7 +76,7 @@ from zerver.tornado.django_api import get_user_events, request_event_queue
from zproject.backends import email_auth_enabled, password_auth_enabled from zproject.backends import email_auth_enabled, password_auth_enabled
class RestartEventException(Exception): class RestartEventError(Exception):
""" """
Special error for handling restart events in apply_events. Special error for handling restart events in apply_events.
""" """
@ -646,7 +646,7 @@ def apply_events(
) -> None: ) -> None:
for event in events: for event in events:
if event["type"] == "restart": if event["type"] == "restart":
raise RestartEventException() raise RestartEventError()
if fetch_event_types is not None and event["type"] not in fetch_event_types: if fetch_event_types is not None and event["type"] not in fetch_event_types:
# TODO: continuing here is not, most precisely, correct. # TODO: continuing here is not, most precisely, correct.
# In theory, an event of one type, e.g. `realm_user`, # In theory, an event of one type, e.g. `realm_user`,
@ -1483,7 +1483,7 @@ def do_events_register(
slim_presence=slim_presence, slim_presence=slim_presence,
include_subscribers=include_subscribers, include_subscribers=include_subscribers,
) )
except RestartEventException: except RestartEventError:
# This represents a rare race condition, where Tornado # This represents a rare race condition, where Tornado
# restarted (and sent `restart` events) while we were waiting # restarted (and sent `restart` events) while we were waiting
# for fetch_initial_state_data to return. To avoid the client # for fetch_initial_state_data to return. To avoid the client

View File

@ -185,7 +185,7 @@ class CannotDeactivateLastUserError(JsonableError):
return _("Cannot deactivate the only {entity}.") return _("Cannot deactivate the only {entity}.")
class InvalidMarkdownIncludeStatement(JsonableError): class InvalidMarkdownIncludeStatementError(JsonableError):
code = ErrorCode.INVALID_MARKDOWN_INCLUDE_STATEMENT code = ErrorCode.INVALID_MARKDOWN_INCLUDE_STATEMENT
data_fields = ["include_statement"] data_fields = ["include_statement"]
@ -197,7 +197,7 @@ class InvalidMarkdownIncludeStatement(JsonableError):
return _("Invalid Markdown include statement: {include_statement}") return _("Invalid Markdown include statement: {include_statement}")
class RateLimited(JsonableError): class RateLimitedError(JsonableError):
code = ErrorCode.RATE_LIMIT_HIT code = ErrorCode.RATE_LIMIT_HIT
http_status_code = 429 http_status_code = 429
@ -232,7 +232,7 @@ class InvalidJSONError(JsonableError):
return _("Malformed JSON") return _("Malformed JSON")
class OrganizationMemberRequired(JsonableError): class OrganizationMemberRequiredError(JsonableError):
code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL
def __init__(self) -> None: def __init__(self) -> None:
@ -243,7 +243,7 @@ class OrganizationMemberRequired(JsonableError):
return _("Must be an organization member") return _("Must be an organization member")
class OrganizationAdministratorRequired(JsonableError): class OrganizationAdministratorRequiredError(JsonableError):
code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL
def __init__(self) -> None: def __init__(self) -> None:
@ -254,7 +254,7 @@ class OrganizationAdministratorRequired(JsonableError):
return _("Must be an organization administrator") return _("Must be an organization administrator")
class OrganizationOwnerRequired(JsonableError): class OrganizationOwnerRequiredError(JsonableError):
code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL code: ErrorCode = ErrorCode.UNAUTHORIZED_PRINCIPAL
def __init__(self) -> None: def __init__(self) -> None:
@ -320,7 +320,7 @@ class PasswordResetRequiredError(AuthenticationFailedError):
return _("Your password has been disabled and needs to be reset") return _("Your password has been disabled and needs to be reset")
class MarkdownRenderingException(Exception): class MarkdownRenderingError(Exception):
pass pass
@ -346,7 +346,7 @@ class WebhookError(JsonableError):
""" """
Intended as a generic exception raised by specific webhook Intended as a generic exception raised by specific webhook
integrations. This class is subclassed by more specific exceptions integrations. This class is subclassed by more specific exceptions
such as UnsupportedWebhookEventType and AnomalousWebhookPayload. such as UnsupportedWebhookEventTypeError and AnomalousWebhookPayloadError.
""" """
data_fields = ["webhook_name"] data_fields = ["webhook_name"]
@ -357,14 +357,14 @@ class WebhookError(JsonableError):
self.webhook_name = "(unknown)" self.webhook_name = "(unknown)"
class UnsupportedWebhookEventType(WebhookError): class UnsupportedWebhookEventTypeError(WebhookError):
"""Intended as an exception for event formats that we know the """Intended as an exception for event formats that we know the
third-party service generates but which Zulip doesn't support / third-party service generates but which Zulip doesn't support /
generate a message for. generate a message for.
Exceptions where we cannot parse the event type, possibly because Exceptions where we cannot parse the event type, possibly because
the event isn't actually from the service in question, should the event isn't actually from the service in question, should
raise AnomalousWebhookPayload. raise AnomalousWebhookPayloadError.
""" """
code = ErrorCode.UNSUPPORTED_WEBHOOK_EVENT_TYPE code = ErrorCode.UNSUPPORTED_WEBHOOK_EVENT_TYPE
@ -379,14 +379,14 @@ class UnsupportedWebhookEventType(WebhookError):
return _("The '{event_type}' event isn't currently supported by the {webhook_name} webhook") return _("The '{event_type}' event isn't currently supported by the {webhook_name} webhook")
class AnomalousWebhookPayload(WebhookError): class AnomalousWebhookPayloadError(WebhookError):
"""Intended as an exception for incoming webhook requests that we """Intended as an exception for incoming webhook requests that we
cannot recognize as having been generated by the service in cannot recognize as having been generated by the service in
question. (E.g. because someone pointed a Jira server at the question. (E.g. because someone pointed a Jira server at the
GitHub integration URL). GitHub integration URL).
If we can parse the event but don't support it, use If we can parse the event but don't support it, use
UnsupportedWebhookEventType. UnsupportedWebhookEventTypeError.
""" """
@ -420,7 +420,7 @@ class InvalidSubdomainError(JsonableError):
return _("Invalid subdomain") return _("Invalid subdomain")
class ZephyrMessageAlreadySentException(Exception): class ZephyrMessageAlreadySentError(Exception):
def __init__(self, message_id: int) -> None: def __init__(self, message_id: int) -> None:
self.message_id = message_id self.message_id = message_id

View File

@ -43,14 +43,14 @@ PLATFORM_TO_SETUP_FILE = {
} }
class InvalidPlatform(Exception): class InvalidPlatformError(Exception):
pass pass
@cache_with_key(lambda platform: f"download_link:{platform}", timeout=60 * 30) @cache_with_key(lambda platform: f"download_link:{platform}", timeout=60 * 30)
def get_latest_github_release_download_link_for_platform(platform: str) -> str: def get_latest_github_release_download_link_for_platform(platform: str) -> str:
if platform not in PLATFORM_TO_SETUP_FILE: if platform not in PLATFORM_TO_SETUP_FILE:
raise InvalidPlatform() raise InvalidPlatformError()
latest_version = get_latest_github_release_version_for_repo("zulip-desktop") latest_version = get_latest_github_release_version_for_repo("zulip-desktop")
if latest_version: if latest_version:

View File

@ -50,7 +50,7 @@ from zerver.lib import mention as mention
from zerver.lib.cache import cache_with_key from zerver.lib.cache import cache_with_key
from zerver.lib.camo import get_camo_url from zerver.lib.camo import get_camo_url
from zerver.lib.emoji import EMOTICON_RE, codepoint_to_name, name_to_codepoint, translate_emoticons from zerver.lib.emoji import EMOTICON_RE, codepoint_to_name, name_to_codepoint, translate_emoticons
from zerver.lib.exceptions import MarkdownRenderingException from zerver.lib.exceptions import MarkdownRenderingError
from zerver.lib.markdown import fenced_code from zerver.lib.markdown import fenced_code
from zerver.lib.markdown.fenced_code import FENCE_RE from zerver.lib.markdown.fenced_code import FENCE_RE
from zerver.lib.mention import ( from zerver.lib.mention import (
@ -63,7 +63,7 @@ from zerver.lib.outgoing_http import OutgoingSession
from zerver.lib.subdomains import is_static_or_current_realm_url from zerver.lib.subdomains import is_static_or_current_realm_url
from zerver.lib.tex import render_tex from zerver.lib.tex import render_tex
from zerver.lib.thumbnail import user_uploads_or_external from zerver.lib.thumbnail import user_uploads_or_external
from zerver.lib.timeout import TimeoutExpired, timeout from zerver.lib.timeout import TimeoutExpiredError, timeout
from zerver.lib.timezone import common_timezones from zerver.lib.timezone import common_timezones
from zerver.lib.types import LinkifierDict from zerver.lib.types import LinkifierDict
from zerver.lib.url_encoding import encode_stream, hash_util_encode from zerver.lib.url_encoding import encode_stream, hash_util_encode
@ -474,7 +474,7 @@ def fetch_tweet_data(tweet_id: str) -> Optional[Dict[str, Any]]:
# formatting timeout. # formatting timeout.
tweet = timeout(3, lambda: api.GetStatus(tweet_id)) tweet = timeout(3, lambda: api.GetStatus(tweet_id))
res = tweet.AsDict() res = tweet.AsDict()
except TimeoutExpired: except TimeoutExpiredError:
# We'd like to try again later and not cache the bad result, # We'd like to try again later and not cache the bad result,
# so we need to re-raise the exception (just as though # so we need to re-raise the exception (just as though
# we were being rate-limited) # we were being rate-limited)
@ -2581,7 +2581,7 @@ def do_convert(
# something huge. # something huge.
MAX_MESSAGE_LENGTH = settings.MAX_MESSAGE_LENGTH MAX_MESSAGE_LENGTH = settings.MAX_MESSAGE_LENGTH
if len(rendering_result.rendered_content) > MAX_MESSAGE_LENGTH * 100: if len(rendering_result.rendered_content) > MAX_MESSAGE_LENGTH * 100:
raise MarkdownRenderingException( raise MarkdownRenderingError(
f"Rendered content exceeds {MAX_MESSAGE_LENGTH * 100} characters (message {logging_message_id})" f"Rendered content exceeds {MAX_MESSAGE_LENGTH * 100} characters (message {logging_message_id})"
) )
return rendering_result return rendering_result
@ -2596,7 +2596,7 @@ def do_convert(
logging_message_id, logging_message_id,
) )
raise MarkdownRenderingException() raise MarkdownRenderingError()
finally: finally:
# These next three lines are slightly paranoid, since # These next three lines are slightly paranoid, since
# we always set these right before actually using the # we always set these right before actually using the

View File

@ -87,7 +87,7 @@ from markdown.preprocessors import Preprocessor
from pygments.lexers import find_lexer_class_by_name from pygments.lexers import find_lexer_class_by_name
from pygments.util import ClassNotFound from pygments.util import ClassNotFound
from zerver.lib.exceptions import MarkdownRenderingException from zerver.lib.exceptions import MarkdownRenderingError
from zerver.lib.markdown.priorities import PREPROCESSOR_PRIORITES from zerver.lib.markdown.priorities import PREPROCESSOR_PRIORITES
from zerver.lib.tex import render_tex from zerver.lib.tex import render_tex
@ -137,7 +137,7 @@ Missing required -X argument in curl command:
regex = r'curl [-](sS)?X "?(GET|DELETE|PATCH|POST)"?' regex = r'curl [-](sS)?X "?(GET|DELETE|PATCH|POST)"?'
if line.startswith("curl"): if line.startswith("curl"):
if re.search(regex, line) is None: if re.search(regex, line) is None:
raise MarkdownRenderingException(error_msg.format(command=line.strip())) raise MarkdownRenderingError(error_msg.format(command=line.strip()))
CODE_VALIDATORS: Dict[Optional[str], Callable[[List[str]], None]] = { CODE_VALIDATORS: Dict[Optional[str], Callable[[List[str]], None]] = {

View File

@ -7,7 +7,7 @@ from markdown import Extension, Markdown
from markdown.blockparser import BlockParser from markdown.blockparser import BlockParser
from markdown.blockprocessors import BlockProcessor from markdown.blockprocessors import BlockProcessor
from zerver.lib.exceptions import InvalidMarkdownIncludeStatement from zerver.lib.exceptions import InvalidMarkdownIncludeStatementError
from zerver.lib.markdown.priorities import BLOCK_PROCESSOR_PRIORITIES from zerver.lib.markdown.priorities import BLOCK_PROCESSOR_PRIORITIES
@ -39,7 +39,7 @@ class IncludeBlockProcessor(BlockProcessor):
with open(os.path.normpath(os.path.join(self.base_path, m[1]))) as f: with open(os.path.normpath(os.path.join(self.base_path, m[1]))) as f:
lines = f.read().splitlines() lines = f.read().splitlines()
except OSError as e: except OSError as e:
raise InvalidMarkdownIncludeStatement(m[0].strip()) from e raise InvalidMarkdownIncludeStatementError(m[0].strip()) from e
for prep in self.parser.md.preprocessors: for prep in self.parser.md.preprocessors:
lines = prep.run(lines) lines = prep.run(lines)

View File

@ -3,7 +3,7 @@ import os
import subprocess import subprocess
class DiffException(Exception): class DiffError(Exception):
pass pass
@ -13,7 +13,7 @@ def diff_strings(output: str, expected_output: str) -> str:
if not os.path.isfile(mdiff_path): # nocoverage if not os.path.isfile(mdiff_path): # nocoverage
msg = "Cannot find mdiff for Markdown diff rendering" msg = "Cannot find mdiff for Markdown diff rendering"
logging.error(msg) logging.error(msg)
raise DiffException(msg) raise DiffError(msg)
command = ["node", mdiff_path, output, expected_output] command = ["node", mdiff_path, output, expected_output]
diff = subprocess.check_output(command, text=True) diff = subprocess.check_output(command, text=True)

View File

@ -186,7 +186,7 @@ def build_narrow_filter(narrow: Collection[Sequence[str]]) -> Callable[[Mapping[
LARGER_THAN_MAX_MESSAGE_ID = 10000000000000000 LARGER_THAN_MAX_MESSAGE_ID = 10000000000000000
class BadNarrowOperator(JsonableError): class BadNarrowOperatorError(JsonableError):
code = ErrorCode.BAD_NARROW code = ErrorCode.BAD_NARROW
data_fields = ["desc"] data_fields = ["desc"]
@ -284,7 +284,7 @@ class NarrowBuilder:
method_name = "by_" + operator.replace("-", "_") method_name = "by_" + operator.replace("-", "_")
method = getattr(self, method_name, None) method = getattr(self, method_name, None)
if method is None: if method is None:
raise BadNarrowOperator("unknown operator " + operator) raise BadNarrowOperatorError("unknown operator " + operator)
if negated: if negated:
maybe_negate = not_ maybe_negate = not_
@ -295,7 +295,7 @@ class NarrowBuilder:
def by_has(self, query: Select, operand: str, maybe_negate: ConditionTransform) -> Select: def by_has(self, query: Select, operand: str, maybe_negate: ConditionTransform) -> Select:
if operand not in ["attachment", "image", "link"]: if operand not in ["attachment", "image", "link"]:
raise BadNarrowOperator("unknown 'has' operand " + operand) raise BadNarrowOperatorError("unknown 'has' operand " + operand)
col_name = "has_" + operand col_name = "has_" + operand
cond = column(col_name, Boolean) cond = column(col_name, Boolean)
return query.where(maybe_negate(cond)) return query.where(maybe_negate(cond))
@ -311,7 +311,7 @@ class NarrowBuilder:
elif operand == "all": elif operand == "all":
return query return query
raise BadNarrowOperator("unknown 'in' operand " + operand) raise BadNarrowOperatorError("unknown 'in' operand " + operand)
def by_is(self, query: Select, operand: str, maybe_negate: ConditionTransform) -> Select: def by_is(self, query: Select, operand: str, maybe_negate: ConditionTransform) -> Select:
# This operator class does not support is_web_public_query. # This operator class does not support is_web_public_query.
@ -338,7 +338,7 @@ class NarrowBuilder:
elif operand == "resolved": elif operand == "resolved":
cond = get_resolved_topic_condition_sa() cond = get_resolved_topic_condition_sa()
return query.where(maybe_negate(cond)) return query.where(maybe_negate(cond))
raise BadNarrowOperator("unknown 'is' operand " + operand) raise BadNarrowOperatorError("unknown 'is' operand " + operand)
_alphanum = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") _alphanum = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
@ -371,9 +371,9 @@ class NarrowBuilder:
stream = get_stream_by_narrow_operand_access_unchecked(operand, self.realm) stream = get_stream_by_narrow_operand_access_unchecked(operand, self.realm)
if self.is_web_public_query and not stream.is_web_public: if self.is_web_public_query and not stream.is_web_public:
raise BadNarrowOperator("unknown web-public stream " + str(operand)) raise BadNarrowOperatorError("unknown web-public stream " + str(operand))
except Stream.DoesNotExist: except Stream.DoesNotExist:
raise BadNarrowOperator("unknown stream " + str(operand)) raise BadNarrowOperatorError("unknown stream " + str(operand))
if self.realm.is_zephyr_mirror_realm: if self.realm.is_zephyr_mirror_realm:
# MIT users expect narrowing to "social" to also show messages to # MIT users expect narrowing to "social" to also show messages to
@ -412,7 +412,7 @@ class NarrowBuilder:
elif operand == "web-public": elif operand == "web-public":
recipient_queryset = get_web_public_streams_queryset(self.realm) recipient_queryset = get_web_public_streams_queryset(self.realm)
else: else:
raise BadNarrowOperator("unknown streams operand " + operand) raise BadNarrowOperatorError("unknown streams operand " + operand)
recipient_ids = recipient_queryset.values_list("recipient_id", flat=True).order_by("id") recipient_ids = recipient_queryset.values_list("recipient_id", flat=True).order_by("id")
cond = column("recipient_id", Integer).in_(recipient_ids) cond = column("recipient_id", Integer).in_(recipient_ids)
@ -472,7 +472,7 @@ class NarrowBuilder:
else: else:
sender = get_user_by_id_in_realm_including_cross_realm(operand, self.realm) sender = get_user_by_id_in_realm_including_cross_realm(operand, self.realm)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
raise BadNarrowOperator("unknown user " + str(operand)) raise BadNarrowOperatorError("unknown user " + str(operand))
cond = column("sender_id", Integer) == literal(sender.id) cond = column("sender_id", Integer) == literal(sender.id)
return query.where(maybe_negate(cond)) return query.where(maybe_negate(cond))
@ -484,7 +484,7 @@ class NarrowBuilder:
self, query: Select, operand: Union[int, str], maybe_negate: ConditionTransform self, query: Select, operand: Union[int, str], maybe_negate: ConditionTransform
) -> Select: ) -> Select:
if not str(operand).isdigit(): if not str(operand).isdigit():
raise BadNarrowOperator("Invalid message ID") raise BadNarrowOperatorError("Invalid message ID")
cond = self.msg_id_column == literal(operand) cond = self.msg_id_column == literal(operand)
return query.where(maybe_negate(cond)) return query.where(maybe_negate(cond))
@ -520,7 +520,7 @@ class NarrowBuilder:
allow_deactivated=True, allow_deactivated=True,
) )
except (JsonableError, ValidationError): except (JsonableError, ValidationError):
raise BadNarrowOperator("unknown user in " + str(operand)) raise BadNarrowOperatorError("unknown user in " + str(operand))
# Group DM # Group DM
if recipient.type == Recipient.HUDDLE: if recipient.type == Recipient.HUDDLE:
@ -576,7 +576,7 @@ class NarrowBuilder:
else: else:
narrow_profile = get_user_by_id_in_realm_including_cross_realm(operand, self.realm) narrow_profile = get_user_by_id_in_realm_including_cross_realm(operand, self.realm)
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
raise BadNarrowOperator("unknown user " + str(operand)) raise BadNarrowOperatorError("unknown user " + str(operand))
self_recipient_ids = [ self_recipient_ids = [
recipient_tuple["recipient_id"] recipient_tuple["recipient_id"]

View File

@ -11,7 +11,7 @@ from django.conf import settings
from django.http import HttpRequest from django.http import HttpRequest
from zerver.lib.cache import cache_with_key from zerver.lib.cache import cache_with_key
from zerver.lib.exceptions import RateLimited from zerver.lib.exceptions import RateLimitedError
from zerver.lib.redis_utils import get_redis_client from zerver.lib.redis_utils import get_redis_client
from zerver.lib.utils import statsd from zerver.lib.utils import statsd
from zerver.models import UserProfile from zerver.models import UserProfile
@ -27,7 +27,7 @@ KEY_PREFIX = ""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class RateLimiterLockingException(Exception): class RateLimiterLockingError(Exception):
pass pass
@ -61,7 +61,7 @@ class RateLimitedObject(ABC):
# Abort this request if the user is over their rate limits # Abort this request if the user is over their rate limits
if ratelimited: if ratelimited:
# Pass information about what kind of entity got limited in the exception: # Pass information about what kind of entity got limited in the exception:
raise RateLimited(time) raise RateLimitedError(time)
calls_remaining, seconds_until_reset = self.api_calls_left() calls_remaining, seconds_until_reset = self.api_calls_left()
@ -483,7 +483,7 @@ class RedisRateLimiterBackend(RateLimiterBackend):
break break
except redis.WatchError: # nocoverage # Ideally we'd have a test for this. except redis.WatchError: # nocoverage # Ideally we'd have a test for this.
if count > 10: if count > 10:
raise RateLimiterLockingException() raise RateLimiterLockingError()
count += 1 count += 1
continue continue
@ -500,7 +500,7 @@ class RedisRateLimiterBackend(RateLimiterBackend):
else: else:
try: try:
cls.incr_ratelimit(entity_key, max_api_calls, max_api_window) cls.incr_ratelimit(entity_key, max_api_calls, max_api_window)
except RateLimiterLockingException: except RateLimiterLockingError:
logger.warning("Deadlock trying to incr_ratelimit for %s", entity_key) logger.warning("Deadlock trying to incr_ratelimit for %s", entity_key)
# rate-limit users who are hitting the API so hard we can't update our stats. # rate-limit users who are hitting the API so hard we can't update our stats.
ratelimited = True ratelimited = True
@ -536,7 +536,7 @@ class RateLimitedSpectatorAttachmentAccessByFile(RateLimitedObject):
def rate_limit_spectator_attachment_access_by_file(path_id: str) -> None: def rate_limit_spectator_attachment_access_by_file(path_id: str) -> None:
ratelimited, _ = RateLimitedSpectatorAttachmentAccessByFile(path_id).rate_limit() ratelimited, _ = RateLimitedSpectatorAttachmentAccessByFile(path_id).rate_limit()
if ratelimited: if ratelimited:
raise RateLimited raise RateLimitedError
def is_local_addr(addr: str) -> bool: def is_local_addr(addr: str) -> bool:
@ -579,7 +579,7 @@ def client_is_exempt_from_rate_limiting(request: HttpRequest) -> bool:
def rate_limit_user(request: HttpRequest, user: UserProfile, domain: str) -> None: def rate_limit_user(request: HttpRequest, user: UserProfile, domain: str) -> None:
"""Returns whether or not a user was rate limited. Will raise a RateLimited exception """Returns whether or not a user was rate limited. Will raise a RateLimitedError exception
if the user has been rate limited, otherwise returns and modifies request to contain if the user has been rate limited, otherwise returns and modifies request to contain
the rate limit information""" the rate limit information"""
if not should_rate_limit(request): if not should_rate_limit(request):

View File

@ -21,7 +21,7 @@ class PushBouncerSession(OutgoingSession):
super().__init__(role="push_bouncer", timeout=30) super().__init__(role="push_bouncer", timeout=30)
class PushNotificationBouncerException(Exception): class PushNotificationBouncerError(Exception):
pass pass
@ -87,7 +87,7 @@ def send_to_push_bouncer(
msg = result_dict["msg"] msg = result_dict["msg"]
if "code" in result_dict and result_dict["code"] == "INVALID_ZULIP_SERVER": if "code" in result_dict and result_dict["code"] == "INVALID_ZULIP_SERVER":
# Invalid Zulip server credentials should email this server's admins # Invalid Zulip server credentials should email this server's admins
raise PushNotificationBouncerException( raise PushNotificationBouncerError(
_("Push notifications bouncer error: {}").format(msg) _("Push notifications bouncer error: {}").format(msg)
) )
else: else:
@ -99,7 +99,7 @@ def send_to_push_bouncer(
# Anything else is unexpected and likely suggests a bug in # Anything else is unexpected and likely suggests a bug in
# this version of Zulip, so we throw an exception that will # this version of Zulip, so we throw an exception that will
# email the server admins. # email the server admins.
raise PushNotificationBouncerException( raise PushNotificationBouncerError(
f"Push notification bouncer returned unexpected status code {res.status_code}" f"Push notification bouncer returned unexpected status code {res.status_code}"
) )

View File

@ -206,11 +206,11 @@ def build_email(
return mail return mail
class EmailNotDeliveredException(Exception): class EmailNotDeliveredError(Exception):
pass pass
class DoubledEmailArgumentException(CommandError): class DoubledEmailArgumentError(CommandError):
def __init__(self, argument_name: str) -> None: def __init__(self, argument_name: str) -> None:
msg = ( msg = (
f"Argument '{argument_name}' is ambiguously present in both options and email template." f"Argument '{argument_name}' is ambiguously present in both options and email template."
@ -218,7 +218,7 @@ class DoubledEmailArgumentException(CommandError):
super().__init__(msg) super().__init__(msg)
class NoEmailArgumentException(CommandError): class NoEmailArgumentError(CommandError):
def __init__(self, argument_name: str) -> None: def __init__(self, argument_name: str) -> None:
msg = f"Argument '{argument_name}' is required in either options or email template." msg = f"Argument '{argument_name}' is required in either options or email template."
super().__init__(msg) super().__init__(msg)
@ -277,7 +277,7 @@ def send_email(
# it will only call .close() if it was not open to begin with # it will only call .close() if it was not open to begin with
if connection.send_messages([mail]) == 0: if connection.send_messages([mail]) == 0:
logger.error("Unknown error sending %s email to %s", template, mail.to) logger.error("Unknown error sending %s email to %s", template, mail.to)
raise EmailNotDeliveredException raise EmailNotDeliveredError
except smtplib.SMTPResponseException as e: except smtplib.SMTPResponseException as e:
logger.exception( logger.exception(
"Error sending %s email to %s with error code %s: %s", "Error sending %s email to %s with error code %s: %s",
@ -287,10 +287,10 @@ def send_email(
e.smtp_error, e.smtp_error,
stack_info=True, stack_info=True,
) )
raise EmailNotDeliveredException raise EmailNotDeliveredError
except smtplib.SMTPException as e: except smtplib.SMTPException as e:
logger.exception("Error sending %s email to %s: %s", template, mail.to, e, stack_info=True) logger.exception("Error sending %s email to %s: %s", template, mail.to, e, stack_info=True)
raise EmailNotDeliveredException raise EmailNotDeliveredError
@backoff.on_exception(backoff.expo, OSError, max_tries=MAX_CONNECTION_TRIES, logger=None) @backoff.on_exception(backoff.expo, OSError, max_tries=MAX_CONNECTION_TRIES, logger=None)
@ -488,9 +488,9 @@ def deliver_scheduled_emails(email: ScheduledEmail) -> None:
def get_header(option: Optional[str], header: Optional[str], name: str) -> str: def get_header(option: Optional[str], header: Optional[str], name: str) -> str:
if option and header: if option and header:
raise DoubledEmailArgumentException(name) raise DoubledEmailArgumentError(name)
if not option and not header: if not option and not header:
raise NoEmailArgumentException(name) raise NoEmailArgumentError(name)
return str(option or header) return str(option or header)
@ -564,7 +564,7 @@ def send_custom_email(
context=context, context=context,
dry_run=options["dry_run"], dry_run=options["dry_run"],
) )
except EmailNotDeliveredException: except EmailNotDeliveredError:
pass pass
if options["dry_run"]: if options["dry_run"]:

View File

@ -9,8 +9,8 @@ from django.utils.translation import gettext as _
from zerver.actions.default_streams import get_default_streams_for_realm from zerver.actions.default_streams import get_default_streams_for_realm
from zerver.lib.exceptions import ( from zerver.lib.exceptions import (
JsonableError, JsonableError,
OrganizationAdministratorRequired, OrganizationAdministratorRequiredError,
OrganizationOwnerRequired, OrganizationOwnerRequiredError,
) )
from zerver.lib.markdown import markdown_convert from zerver.lib.markdown import markdown_convert
from zerver.lib.stream_subscription import ( from zerver.lib.stream_subscription import (
@ -318,7 +318,7 @@ def check_stream_access_for_delete_or_update(
if sub is None and stream.invite_only: if sub is None and stream.invite_only:
raise JsonableError(error) raise JsonableError(error)
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
def access_stream_for_delete_or_update( def access_stream_for_delete_or_update(
@ -739,7 +739,7 @@ def list_to_streams(
if message_retention_days_not_none: if message_retention_days_not_none:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
user_profile.realm.ensure_not_on_limited_plan() user_profile.realm.ensure_not_on_limited_plan()

View File

@ -66,7 +66,7 @@ from zerver.lib.streams import (
from zerver.lib.subscription_info import gather_subscriptions from zerver.lib.subscription_info import gather_subscriptions
from zerver.lib.test_console_output import ( from zerver.lib.test_console_output import (
ExtraConsoleOutputFinder, ExtraConsoleOutputFinder,
ExtraConsoleOutputInTestException, ExtraConsoleOutputInTestError,
tee_stderr_and_find_extra_console_output, tee_stderr_and_find_extra_console_output,
tee_stdout_and_find_extra_console_output, tee_stdout_and_find_extra_console_output,
) )
@ -192,7 +192,7 @@ Output:
{extra_output_finder.full_extra_output.decode(errors="replace")} {extra_output_finder.full_extra_output.decode(errors="replace")}
-------------------------------------------- --------------------------------------------
""" """
raise ExtraConsoleOutputInTestException(exception_message) raise ExtraConsoleOutputInTestError(exception_message)
return test_result return test_result
""" """

View File

@ -7,7 +7,7 @@ from types import TracebackType
from typing import IO, Iterable, Iterator, List, Optional, Type from typing import IO, Iterable, Iterator, List, Optional, Type
class ExtraConsoleOutputInTestException(Exception): class ExtraConsoleOutputInTestError(Exception):
pass pass

View File

@ -9,7 +9,7 @@ from typing import Callable, Optional, Tuple, Type, TypeVar
# Based on https://code.activestate.com/recipes/483752/ # Based on https://code.activestate.com/recipes/483752/
class TimeoutExpired(Exception): class TimeoutExpiredError(Exception):
"""Exception raised when a function times out.""" """Exception raised when a function times out."""
def __str__(self) -> str: def __str__(self) -> str:
@ -24,7 +24,7 @@ def timeout(timeout: float, func: Callable[[], ResultT]) -> ResultT:
Return its return value, or raise an exception, Return its return value, or raise an exception,
within approximately 'timeout' seconds. within approximately 'timeout' seconds.
The function may receive a TimeoutExpired exception The function may receive a TimeoutExpiredError exception
anywhere in its code, which could have arbitrary anywhere in its code, which could have arbitrary
unsafe effects (resources not released, etc.). unsafe effects (resources not released, etc.).
It might also fail to receive the exception and It might also fail to receive the exception and
@ -57,11 +57,11 @@ def timeout(timeout: float, func: Callable[[], ResultT]) -> ResultT:
def raise_async_timeout(self) -> None: def raise_async_timeout(self) -> None:
# This function is called from another thread; we attempt # This function is called from another thread; we attempt
# to raise a TimeoutExpired in _this_ thread. # to raise a TimeoutExpiredError in _this_ thread.
assert self.ident is not None assert self.ident is not None
ctypes.pythonapi.PyThreadState_SetAsyncExc( ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_ulong(self.ident), ctypes.c_ulong(self.ident),
ctypes.py_object(TimeoutExpired), ctypes.py_object(TimeoutExpiredError),
) )
thread = TimeoutThread() thread = TimeoutThread()
@ -86,7 +86,7 @@ def timeout(timeout: float, func: Callable[[], ResultT]) -> ResultT:
# we just ignore it. # we just ignore it.
if thread.is_alive(): if thread.is_alive():
logging.warning("Failed to time out backend thread") logging.warning("Failed to time out backend thread")
raise TimeoutExpired raise TimeoutExpiredError
if thread.exc_info[1] is not None: if thread.exc_info[1] is not None:
# Died with some other exception; re-raise it # Died with some other exception; re-raise it

View File

@ -2,13 +2,13 @@ import calendar
import datetime import datetime
class TimeZoneNotUTCException(Exception): class TimeZoneNotUTCError(Exception):
pass pass
def verify_UTC(dt: datetime.datetime) -> None: def verify_UTC(dt: datetime.datetime) -> None:
if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) != datetime.timezone.utc.utcoffset(dt): if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) != datetime.timezone.utc.utcoffset(dt):
raise TimeZoneNotUTCException(f"Datetime {dt} does not have a UTC time zone.") raise TimeZoneNotUTCError(f"Datetime {dt} does not have a UTC time zone.")
def convert_to_UTC(dt: datetime.datetime) -> datetime.datetime: def convert_to_UTC(dt: datetime.datetime) -> datetime.datetime:

View File

@ -21,8 +21,8 @@ from zerver.lib.cache import (
) )
from zerver.lib.exceptions import ( from zerver.lib.exceptions import (
JsonableError, JsonableError,
OrganizationAdministratorRequired, OrganizationAdministratorRequiredError,
OrganizationOwnerRequired, OrganizationOwnerRequiredError,
) )
from zerver.lib.timezone import canonicalize_timezone from zerver.lib.timezone import canonicalize_timezone
from zerver.lib.types import ProfileDataElementUpdateDict, ProfileDataElementValue from zerver.lib.types import ProfileDataElementUpdateDict, ProfileDataElementValue
@ -145,12 +145,12 @@ def check_bot_creation_policy(user_profile: UserProfile, bot_type: int) -> None:
if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_EVERYONE: if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_EVERYONE:
return return
if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_ADMINS_ONLY: if user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_ADMINS_ONLY:
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
if ( if (
user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_LIMIT_GENERIC_BOTS user_profile.realm.bot_creation_policy == Realm.BOT_CREATION_LIMIT_GENERIC_BOTS
and bot_type == UserProfile.DEFAULT_BOT and bot_type == UserProfile.DEFAULT_BOT
): ):
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
def check_valid_bot_type(user_profile: UserProfile, bot_type: int) -> None: def check_valid_bot_type(user_profile: UserProfile, bot_type: int) -> None:
@ -255,7 +255,7 @@ def access_bot_by_id(user_profile: UserProfile, user_id: int) -> UserProfile:
# default, because it can be abused to send spam. Requiring an # default, because it can be abused to send spam. Requiring an
# owner is intended to ensure organizational responsibility # owner is intended to ensure organizational responsibility
# for use of this permission. # for use of this permission.
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
return target return target

View File

@ -57,7 +57,7 @@ def notify_bot_owner_about_invalid_json(
) )
class MissingHTTPEventHeader(JsonableError): class MissingHTTPEventHeaderError(JsonableError):
code = ErrorCode.MISSING_HTTP_EVENT_HEADER code = ErrorCode.MISSING_HTTP_EVENT_HEADER
data_fields = ["header"] data_fields = ["header"]
@ -176,7 +176,7 @@ def validate_extract_webhook_http_header(
request.user, request.user.realm, message_body request.user, request.user.realm, message_body
) )
raise MissingHTTPEventHeader(header) raise MissingHTTPEventHeaderError(header)
return extracted_header return extracted_header

View File

@ -15,7 +15,7 @@ from django.db import transaction
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from zerver.lib.logging_util import log_to_file from zerver.lib.logging_util import log_to_file
from zerver.lib.send_email import EmailNotDeliveredException, deliver_scheduled_emails from zerver.lib.send_email import EmailNotDeliveredError, deliver_scheduled_emails
from zerver.models import ScheduledEmail from zerver.models import ScheduledEmail
## Setup ## ## Setup ##
@ -46,7 +46,7 @@ Usage: ./manage.py deliver_scheduled_emails
if job: if job:
try: try:
deliver_scheduled_emails(job) deliver_scheduled_emails(job)
except EmailNotDeliveredException: except EmailNotDeliveredError:
logger.warning("%r not delivered", job) logger.warning("%r not delivered", job)
else: else:
time.sleep(10) time.sleep(10)

View File

@ -9,7 +9,7 @@ from django.db import transaction
from zerver.lib.logging_util import log_to_file from zerver.lib.logging_util import log_to_file
from zerver.lib.management import ZulipBaseCommand from zerver.lib.management import ZulipBaseCommand
from zerver.models import UserProfile from zerver.models import UserProfile
from zproject.backends import ZulipLDAPException, sync_user_from_ldap from zproject.backends import ZulipLDAPError, sync_user_from_ldap
## Setup ## ## Setup ##
logger = logging.getLogger("zulip.sync_ldap_user_data") logger = logging.getLogger("zulip.sync_ldap_user_data")
@ -29,7 +29,7 @@ def sync_ldap_user_data(
# does not exist. # does not exist.
try: try:
sync_user_from_ldap(u, logger) sync_user_from_ldap(u, logger)
except ZulipLDAPException as e: except ZulipLDAPError as e:
logger.error("Error attempting to update user %s:", u.delivery_email) logger.error("Error attempting to update user %s:", u.delivery_email)
logger.error(e.args[0]) logger.error(e.args[0])

View File

@ -81,7 +81,7 @@ from zerver.lib.cache import (
user_profile_by_id_cache_key, user_profile_by_id_cache_key,
user_profile_cache_key, user_profile_cache_key,
) )
from zerver.lib.exceptions import JsonableError, RateLimited from zerver.lib.exceptions import JsonableError, RateLimitedError
from zerver.lib.pysa import mark_sanitized from zerver.lib.pysa import mark_sanitized
from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.timestamp import datetime_to_timestamp
from zerver.lib.types import ( from zerver.lib.types import (
@ -3506,7 +3506,7 @@ def validate_attachment_request_for_spectator_access(
from zerver.lib.rate_limiter import rate_limit_spectator_attachment_access_by_file from zerver.lib.rate_limiter import rate_limit_spectator_attachment_access_by_file
rate_limit_spectator_attachment_access_by_file(attachment.path_id) rate_limit_spectator_attachment_access_by_file(attachment.path_id)
except RateLimited: except RateLimitedError:
return False return False
return True return True
@ -4672,7 +4672,7 @@ class BotConfigData(models.Model):
unique_together = ("bot_profile", "key") unique_together = ("bot_profile", "key")
class InvalidFakeEmailDomain(Exception): class InvalidFakeEmailDomainError(Exception):
pass pass
@ -4688,7 +4688,7 @@ def get_fake_email_domain(realm: Realm) -> str:
# Check that the fake email domain can be used to form valid email addresses. # Check that the fake email domain can be used to form valid email addresses.
validate_email(Address(username="bot", domain=settings.FAKE_EMAIL_DOMAIN).addr_spec) validate_email(Address(username="bot", domain=settings.FAKE_EMAIL_DOMAIN).addr_spec)
except ValidationError: except ValidationError:
raise InvalidFakeEmailDomain( raise InvalidFakeEmailDomainError(
settings.FAKE_EMAIL_DOMAIN + " is not a valid domain. " settings.FAKE_EMAIL_DOMAIN + " is not a valid domain. "
"Consider setting the FAKE_EMAIL_DOMAIN setting." "Consider setting the FAKE_EMAIL_DOMAIN setting."
) )

View File

@ -71,7 +71,7 @@ from zerver.lib.email_validation import (
get_realm_email_validator, get_realm_email_validator,
validate_email_is_valid, validate_email_is_valid,
) )
from zerver.lib.exceptions import JsonableError, RateLimited from zerver.lib.exceptions import JsonableError, RateLimitedError
from zerver.lib.initial_password import initial_password from zerver.lib.initial_password import initial_password
from zerver.lib.mobile_auth_otp import otp_decrypt_api_key from zerver.lib.mobile_auth_otp import otp_decrypt_api_key
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
@ -127,6 +127,8 @@ from zproject.backends import (
GitHubAuthBackend, GitHubAuthBackend,
GitLabAuthBackend, GitLabAuthBackend,
GoogleAuthBackend, GoogleAuthBackend,
NoMatchingLDAPUserError,
OutsideLDAPDomainError,
PopulateUserLDAPError, PopulateUserLDAPError,
RateLimitedAuthenticationByUsername, RateLimitedAuthenticationByUsername,
SAMLAuthBackend, SAMLAuthBackend,
@ -136,9 +138,7 @@ from zproject.backends import (
ZulipDummyBackend, ZulipDummyBackend,
ZulipLDAPAuthBackend, ZulipLDAPAuthBackend,
ZulipLDAPConfigurationError, ZulipLDAPConfigurationError,
ZulipLDAPException, ZulipLDAPError,
ZulipLDAPExceptionNoMatchingLDAPUser,
ZulipLDAPExceptionOutsideDomain,
ZulipLDAPUser, ZulipLDAPUser,
ZulipLDAPUserPopulator, ZulipLDAPUserPopulator,
ZulipRemoteUserBackend, ZulipRemoteUserBackend,
@ -672,9 +672,9 @@ class RateLimitAuthenticationTests(ZulipTestCase):
self.assertIsNone(attempt_authentication(username, wrong_password)) self.assertIsNone(attempt_authentication(username, wrong_password))
# 2 failed attempts is the limit, so the next ones should get blocked, # 2 failed attempts is the limit, so the next ones should get blocked,
# even with the correct password. # even with the correct password.
with self.assertRaises(RateLimited): with self.assertRaises(RateLimitedError):
attempt_authentication(username, correct_password) attempt_authentication(username, correct_password)
with self.assertRaises(RateLimited): with self.assertRaises(RateLimitedError):
attempt_authentication(username, wrong_password) attempt_authentication(username, wrong_password)
# After enough time passes, more authentication attempts can be made: # After enough time passes, more authentication attempts can be made:
@ -690,7 +690,7 @@ class RateLimitAuthenticationTests(ZulipTestCase):
self.assertIsNone(attempt_authentication(username, wrong_password)) self.assertIsNone(attempt_authentication(username, wrong_password))
self.assertIsNone(attempt_authentication(username, wrong_password)) self.assertIsNone(attempt_authentication(username, wrong_password))
# But the third attempt goes over the limit: # But the third attempt goes over the limit:
with self.assertRaises(RateLimited): with self.assertRaises(RateLimitedError):
attempt_authentication(username, wrong_password) attempt_authentication(username, wrong_password)
# Resetting the password also clears the rate-limit # Resetting the password also clears the rate-limit
@ -5529,7 +5529,7 @@ class DjangoToLDAPUsernameTests(ZulipTestCase):
self.assertEqual(self.backend.django_to_ldap_username("hamlet"), "hamlet") self.assertEqual(self.backend.django_to_ldap_username("hamlet"), "hamlet")
self.assertEqual(self.backend.django_to_ldap_username("hamlet@zulip.com"), "hamlet") self.assertEqual(self.backend.django_to_ldap_username("hamlet@zulip.com"), "hamlet")
with self.assertRaisesRegex( with self.assertRaisesRegex(
ZulipLDAPExceptionOutsideDomain, OutsideLDAPDomainError,
"Email hamlet@example.com does not match LDAP domain zulip.com.", "Email hamlet@example.com does not match LDAP domain zulip.com.",
): ):
self.backend.django_to_ldap_username("hamlet@example.com") self.backend.django_to_ldap_username("hamlet@example.com")
@ -5556,7 +5556,7 @@ class DjangoToLDAPUsernameTests(ZulipTestCase):
self.backend.django_to_ldap_username("hamlet@zulip.com"), self.ldap_username("hamlet") self.backend.django_to_ldap_username("hamlet@zulip.com"), self.ldap_username("hamlet")
) )
# If there are no matches through the email search, raise exception: # If there are no matches through the email search, raise exception:
with self.assertRaises(ZulipLDAPExceptionNoMatchingLDAPUser): with self.assertRaises(NoMatchingLDAPUserError):
self.backend.django_to_ldap_username("no_such_email@example.com") self.backend.django_to_ldap_username("no_such_email@example.com")
self.assertEqual( self.assertEqual(
@ -5564,7 +5564,7 @@ class DjangoToLDAPUsernameTests(ZulipTestCase):
) )
with self.assertLogs(level="WARNING") as m: with self.assertLogs(level="WARNING") as m:
with self.assertRaises(ZulipLDAPExceptionNoMatchingLDAPUser): with self.assertRaises(NoMatchingLDAPUserError):
self.backend.django_to_ldap_username("shared_email@zulip.com") self.backend.django_to_ldap_username("shared_email@zulip.com")
self.assertEqual( self.assertEqual(
m.output, m.output,
@ -5938,19 +5938,19 @@ class TestLDAP(ZulipLDAPTestCase):
realm.save() realm.save()
email = "spam@mailnator.com" email = "spam@mailnator.com"
with self.assertRaisesRegex(ZulipLDAPException, "Email validation failed."): with self.assertRaisesRegex(ZulipLDAPError, "Email validation failed."):
self.backend.get_or_build_user(email, _LDAPUser()) self.backend.get_or_build_user(email, _LDAPUser())
realm.emails_restricted_to_domains = True realm.emails_restricted_to_domains = True
realm.save(update_fields=["emails_restricted_to_domains"]) realm.save(update_fields=["emails_restricted_to_domains"])
email = "spam+spam@mailnator.com" email = "spam+spam@mailnator.com"
with self.assertRaisesRegex(ZulipLDAPException, "Email validation failed."): with self.assertRaisesRegex(ZulipLDAPError, "Email validation failed."):
self.backend.get_or_build_user(email, _LDAPUser()) self.backend.get_or_build_user(email, _LDAPUser())
email = "spam@acme.com" email = "spam@acme.com"
with self.assertRaisesRegex( with self.assertRaisesRegex(
ZulipLDAPException, "This email domain isn't allowed in this organization." ZulipLDAPError, "This email domain isn't allowed in this organization."
): ):
self.backend.get_or_build_user(email, _LDAPUser()) self.backend.get_or_build_user(email, _LDAPUser())
@ -6167,7 +6167,7 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
def test_too_short_name(self) -> None: def test_too_short_name(self) -> None:
self.change_ldap_user_attr("hamlet", "cn", "a") self.change_ldap_user_attr("hamlet", "cn", "a")
with self.assertRaises(ZulipLDAPException), self.assertLogs( with self.assertRaises(ZulipLDAPError), self.assertLogs(
"django_auth_ldap", "WARNING" "django_auth_ldap", "WARNING"
) as warn_log: ) as warn_log:
self.perform_ldap_sync(self.example_user("hamlet")) self.perform_ldap_sync(self.example_user("hamlet"))
@ -6417,7 +6417,7 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
} }
): ):
with self.assertRaisesRegex( with self.assertRaisesRegex(
ZulipLDAPException, "Custom profile field with name non_existent not found" ZulipLDAPError, "Custom profile field with name non_existent not found"
), self.assertLogs("django_auth_ldap", "WARNING") as warn_log: ), self.assertLogs("django_auth_ldap", "WARNING") as warn_log:
self.perform_ldap_sync(self.example_user("hamlet")) self.perform_ldap_sync(self.example_user("hamlet"))
self.assertEqual( self.assertEqual(
@ -6437,7 +6437,7 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
} }
): ):
with self.assertRaisesRegex( with self.assertRaisesRegex(
ZulipLDAPException, "Invalid data for birthday field" ZulipLDAPError, "Invalid data for birthday field"
), self.assertLogs("django_auth_ldap", "WARNING") as warn_log: ), self.assertLogs("django_auth_ldap", "WARNING") as warn_log:
self.perform_ldap_sync(self.example_user("hamlet")) self.perform_ldap_sync(self.example_user("hamlet"))
self.assertEqual( self.assertEqual(

View File

@ -6,7 +6,7 @@ from django.conf import settings
from zerver.apps import flush_cache from zerver.apps import flush_cache
from zerver.lib.cache import ( from zerver.lib.cache import (
MEMCACHED_MAX_KEY_LENGTH, MEMCACHED_MAX_KEY_LENGTH,
InvalidCacheKeyException, InvalidCacheKeyError,
bulk_cached_fetch, bulk_cached_fetch,
cache_delete, cache_delete,
cache_delete_many, cache_delete_many,
@ -38,18 +38,18 @@ class AppsTest(ZulipTestCase):
class CacheKeyValidationTest(ZulipTestCase): class CacheKeyValidationTest(ZulipTestCase):
def test_validate_cache_key(self) -> None: def test_validate_cache_key(self) -> None:
validate_cache_key("nice_Ascii:string!~") validate_cache_key("nice_Ascii:string!~")
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
validate_cache_key("utf8_character:ą") validate_cache_key("utf8_character:ą")
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
validate_cache_key("new_line_character:\n") validate_cache_key("new_line_character:\n")
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
validate_cache_key("control_character:\r") validate_cache_key("control_character:\r")
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
validate_cache_key("whitespace_character: ") validate_cache_key("whitespace_character: ")
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
validate_cache_key("too_long:" + "X" * MEMCACHED_MAX_KEY_LENGTH) validate_cache_key("too_long:" + "X" * MEMCACHED_MAX_KEY_LENGTH)
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
# validate_cache_key does validation on a key with the # validate_cache_key does validation on a key with the
# KEY_PREFIX appended to the start, so even though we're # KEY_PREFIX appended to the start, so even though we're
# passing something "short enough" here, it becomes too # passing something "short enough" here, it becomes too
@ -59,18 +59,18 @@ class CacheKeyValidationTest(ZulipTestCase):
def test_cache_functions_raise_exception(self) -> None: def test_cache_functions_raise_exception(self) -> None:
invalid_key = "invalid_character:\n" invalid_key = "invalid_character:\n"
good_key = "good_key" good_key = "good_key"
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_get(invalid_key) cache_get(invalid_key)
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_set(invalid_key, 0) cache_set(invalid_key, 0)
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_delete(invalid_key) cache_delete(invalid_key)
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_get_many([good_key, invalid_key]) cache_get_many([good_key, invalid_key])
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_set_many({good_key: 0, invalid_key: 1}) cache_set_many({good_key: 0, invalid_key: 1})
with self.assertRaises(InvalidCacheKeyException): with self.assertRaises(InvalidCacheKeyError):
cache_delete_many([good_key, invalid_key]) cache_delete_many([good_key, invalid_key])
@ -248,11 +248,11 @@ class GenericBulkCachedFetchTest(ZulipTestCase):
# Get the user cached: # Get the user cached:
get_user_profile_by_id(hamlet.id) get_user_profile_by_id(hamlet.id)
class CustomException(Exception): class CustomError(Exception):
pass pass
def query_function(ids: List[int]) -> List[UserProfile]: def query_function(ids: List[int]) -> List[UserProfile]:
raise CustomException("The query function was called") raise CustomError("The query function was called")
# query_function shouldn't be called, because the only requested object # query_function shouldn't be called, because the only requested object
# is already cached: # is already cached:
@ -268,7 +268,7 @@ class GenericBulkCachedFetchTest(ZulipTestCase):
self.assertEqual(info_log.output, ["INFO:root:Clearing memcached cache after migrations"]) self.assertEqual(info_log.output, ["INFO:root:Clearing memcached cache after migrations"])
# With the cache flushed, the query_function should get called: # With the cache flushed, the query_function should get called:
with self.assertRaises(CustomException): with self.assertRaises(CustomError):
result = bulk_cached_fetch( result = bulk_cached_fetch(
cache_key_function=user_profile_by_id_cache_key, cache_key_function=user_profile_by_id_cache_key,
query_function=query_function, query_function=query_function,
@ -277,18 +277,18 @@ class GenericBulkCachedFetchTest(ZulipTestCase):
) )
def test_empty_object_ids_list(self) -> None: def test_empty_object_ids_list(self) -> None:
class CustomException(Exception): class CustomError(Exception):
pass pass
def cache_key_function( def cache_key_function(
email: str, email: str,
) -> str: # nocoverage -- this is just here to make sure it's not called ) -> str: # nocoverage -- this is just here to make sure it's not called
raise CustomException("The cache key function was called") raise CustomError("The cache key function was called")
def query_function( def query_function(
emails: List[str], emails: List[str],
) -> List[UserProfile]: # nocoverage -- this is just here to make sure it's not called ) -> List[UserProfile]: # nocoverage -- this is just here to make sure it's not called
raise CustomException("The query function was called") raise CustomError("The query function was called")
# query_function and cache_key_function shouldn't be called, because # query_function and cache_key_function shouldn't be called, because
# objects_ids is empty, so there's nothing to do. # objects_ids is empty, so there's nothing to do.

View File

@ -43,7 +43,7 @@ from zerver.lib.exceptions import (
InvalidAPIKeyFormatError, InvalidAPIKeyFormatError,
InvalidJSONError, InvalidJSONError,
JsonableError, JsonableError,
UnsupportedWebhookEventType, UnsupportedWebhookEventTypeError,
) )
from zerver.lib.initial_password import initial_password from zerver.lib.initial_password import initial_password
from zerver.lib.rate_limiter import is_local_addr from zerver.lib.rate_limiter import is_local_addr
@ -315,7 +315,7 @@ class DecoratorTestCase(ZulipTestCase):
def my_webhook_raises_exception_unsupported_event( def my_webhook_raises_exception_unsupported_event(
request: HttpRequest, user_profile: UserProfile request: HttpRequest, user_profile: UserProfile
) -> HttpResponse: ) -> HttpResponse:
raise UnsupportedWebhookEventType("test_event") raise UnsupportedWebhookEventTypeError("test_event")
webhook_bot_email = "webhook-bot@zulip.com" webhook_bot_email = "webhook-bot@zulip.com"
webhook_bot_realm = get_realm("zulip") webhook_bot_realm = get_realm("zulip")
@ -410,7 +410,7 @@ class DecoratorTestCase(ZulipTestCase):
request.POST["api_key"] = webhook_bot_api_key request.POST["api_key"] = webhook_bot_api_key
exception_msg = "The 'test_event' event isn't currently supported by the ClientName webhook" exception_msg = "The 'test_event' event isn't currently supported by the ClientName webhook"
with self.assertLogs("zulip.zerver.webhooks.unsupported", level="ERROR") as log: with self.assertLogs("zulip.zerver.webhooks.unsupported", level="ERROR") as log:
with self.assertRaisesRegex(UnsupportedWebhookEventType, exception_msg): with self.assertRaisesRegex(UnsupportedWebhookEventTypeError, exception_msg):
request.body = b"invalidjson" request.body = b"invalidjson"
request.content_type = "application/json" request.content_type = "application/json"
request.META["HTTP_X_CUSTOM_HEADER"] = "custom_value" request.META["HTTP_X_CUSTOM_HEADER"] = "custom_value"
@ -564,7 +564,7 @@ class DecoratorLoggingTestCase(ZulipTestCase):
def my_webhook_raises_exception( def my_webhook_raises_exception(
request: HttpRequest, user_profile: UserProfile request: HttpRequest, user_profile: UserProfile
) -> HttpResponse: ) -> HttpResponse:
raise UnsupportedWebhookEventType("test_event") raise UnsupportedWebhookEventTypeError("test_event")
webhook_bot_email = "webhook-bot@zulip.com" webhook_bot_email = "webhook-bot@zulip.com"
@ -582,7 +582,7 @@ class DecoratorLoggingTestCase(ZulipTestCase):
exception_msg = ( exception_msg = (
"The 'test_event' event isn't currently supported by the ClientName webhook" "The 'test_event' event isn't currently supported by the ClientName webhook"
) )
with self.assertRaisesRegex(UnsupportedWebhookEventType, exception_msg): with self.assertRaisesRegex(UnsupportedWebhookEventTypeError, exception_msg):
my_webhook_raises_exception(request) my_webhook_raises_exception(request)
mock_exception.assert_called_with(exception_msg, stack_info=True) mock_exception.assert_called_with(exception_msg, stack_info=True)

View File

@ -110,10 +110,10 @@ class TestCustomEmails(ZulipTestCase):
email_subject = "subject_test" email_subject = "subject_test"
markdown_template_path = "zerver/tests/fixtures/email/custom_emails/email_base_headers_no_headers_test.source.html" markdown_template_path = "zerver/tests/fixtures/email/custom_emails/email_base_headers_no_headers_test.source.html"
from zerver.lib.send_email import NoEmailArgumentException from zerver.lib.send_email import NoEmailArgumentError
self.assertRaises( self.assertRaises(
NoEmailArgumentException, NoEmailArgumentError,
send_custom_email, send_custom_email,
[hamlet], [hamlet],
options={ options={
@ -124,7 +124,7 @@ class TestCustomEmails(ZulipTestCase):
) )
self.assertRaises( self.assertRaises(
NoEmailArgumentException, NoEmailArgumentError,
send_custom_email, send_custom_email,
[hamlet], [hamlet],
options={ options={
@ -142,10 +142,10 @@ class TestCustomEmails(ZulipTestCase):
"zerver/tests/fixtures/email/custom_emails/email_base_headers_test.source.html" "zerver/tests/fixtures/email/custom_emails/email_base_headers_test.source.html"
) )
from zerver.lib.send_email import DoubledEmailArgumentException from zerver.lib.send_email import DoubledEmailArgumentError
self.assertRaises( self.assertRaises(
DoubledEmailArgumentException, DoubledEmailArgumentError,
send_custom_email, send_custom_email,
[hamlet], [hamlet],
options={ options={
@ -156,7 +156,7 @@ class TestCustomEmails(ZulipTestCase):
) )
self.assertRaises( self.assertRaises(
DoubledEmailArgumentException, DoubledEmailArgumentError,
send_custom_email, send_custom_email,
[hamlet], [hamlet],
options={ options={

View File

@ -2,7 +2,7 @@ from unittest.mock import patch
import orjson import orjson
from zerver.lib.bot_lib import EmbeddedBotQuitException from zerver.lib.bot_lib import EmbeddedBotQuitError
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.models import ( from zerver.models import (
UserProfile, UserProfile,
@ -75,7 +75,7 @@ class TestEmbeddedBotMessaging(ZulipTestCase):
assert self.bot_profile is not None assert self.bot_profile is not None
with patch( with patch(
"zulip_bots.bots.helloworld.helloworld.HelloWorldHandler.handle_message", "zulip_bots.bots.helloworld.helloworld.HelloWorldHandler.handle_message",
side_effect=EmbeddedBotQuitException("I'm quitting!"), side_effect=EmbeddedBotQuitError("I'm quitting!"),
): ):
with self.assertLogs(level="WARNING") as m: with self.assertLogs(level="WARNING") as m:
self.send_stream_message( self.send_stream_message(

View File

@ -182,7 +182,7 @@ from zerver.lib.event_schema import (
check_user_topic, check_user_topic,
) )
from zerver.lib.events import ( from zerver.lib.events import (
RestartEventException, RestartEventError,
apply_events, apply_events,
fetch_initial_state_data, fetch_initial_state_data,
post_process_state, post_process_state,
@ -2499,7 +2499,7 @@ class NormalActionsTest(BaseAction):
check_has_zoom_token("events[0]", events[0], value=False) check_has_zoom_token("events[0]", events[0], value=False)
def test_restart_event(self) -> None: def test_restart_event(self) -> None:
with self.assertRaises(RestartEventException): with self.assertRaises(RestartEventError):
self.verify_action(lambda: send_restart_events(immediate=True)) self.verify_action(lambda: send_restart_events(immediate=True))
def test_display_setting_event_not_sent(self) -> None: def test_display_setting_event_not_sent(self) -> None:

View File

@ -17,7 +17,7 @@ from zerver.lib.cache import cache_delete
from zerver.lib.rate_limiter import ( from zerver.lib.rate_limiter import (
RateLimitedIPAddr, RateLimitedIPAddr,
RateLimitedUser, RateLimitedUser,
RateLimiterLockingException, RateLimiterLockingError,
add_ratelimit_rule, add_ratelimit_rule,
get_tor_ips, get_tor_ips,
remove_ratelimit_rule, remove_ratelimit_rule,
@ -447,7 +447,7 @@ class RateLimitTests(ZulipTestCase):
with mock.patch( with mock.patch(
"zerver.lib.rate_limiter.RedisRateLimiterBackend.incr_ratelimit", "zerver.lib.rate_limiter.RedisRateLimiterBackend.incr_ratelimit",
side_effect=RateLimiterLockingException, side_effect=RateLimiterLockingError,
): ):
with self.assertLogs("zerver.lib.rate_limiter", level="WARNING") as m: with self.assertLogs("zerver.lib.rate_limiter", level="WARNING") as m:
result = self.send_api_message(user, "some stuff") result = self.send_api_message(user, "some stuff")

View File

@ -2,7 +2,10 @@ import requests
import responses import responses
from zerver.lib.cache import cache_delete from zerver.lib.cache import cache_delete
from zerver.lib.github import InvalidPlatform, get_latest_github_release_download_link_for_platform from zerver.lib.github import (
InvalidPlatformError,
get_latest_github_release_download_link_for_platform,
)
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
logger_string = "zerver.lib.github" logger_string = "zerver.lib.github"
@ -81,5 +84,5 @@ class GitHubTestCase(ZulipTestCase):
[f"ERROR:{logger_string}:App download link is broken {download_link}"], [f"ERROR:{logger_string}:App download link is broken {download_link}"],
) )
with self.assertRaises(InvalidPlatform): with self.assertRaises(InvalidPlatformError):
get_latest_github_release_download_link_for_platform("plan9") get_latest_github_release_download_link_for_platform("plan9")

View File

@ -21,7 +21,7 @@ from zerver.lib.alert_words import get_alert_word_automaton
from zerver.lib.camo import get_camo_url from zerver.lib.camo import get_camo_url
from zerver.lib.create_user import create_user from zerver.lib.create_user import create_user
from zerver.lib.emoji import get_emoji_url from zerver.lib.emoji import get_emoji_url
from zerver.lib.exceptions import JsonableError, MarkdownRenderingException from zerver.lib.exceptions import JsonableError, MarkdownRenderingError
from zerver.lib.markdown import ( from zerver.lib.markdown import (
MarkdownListPreprocessor, MarkdownListPreprocessor,
MessageRenderingResult, MessageRenderingResult,
@ -2900,7 +2900,7 @@ class MarkdownApiTests(ZulipTestCase):
class MarkdownErrorTests(ZulipTestCase): class MarkdownErrorTests(ZulipTestCase):
def test_markdown_error_handling(self) -> None: def test_markdown_error_handling(self) -> None:
with self.simulated_markdown_failure(): with self.simulated_markdown_failure():
with self.assertRaises(MarkdownRenderingException): with self.assertRaises(MarkdownRenderingError):
markdown_convert_wrapper("") markdown_convert_wrapper("")
def test_send_message_errors(self) -> None: def test_send_message_errors(self) -> None:
@ -2921,7 +2921,7 @@ class MarkdownErrorTests(ZulipTestCase):
with mock.patch("zerver.lib.markdown.timeout", return_value=msg), mock.patch( with mock.patch("zerver.lib.markdown.timeout", return_value=msg), mock.patch(
"zerver.lib.markdown.markdown_logger" "zerver.lib.markdown.markdown_logger"
): ):
with self.assertRaises(MarkdownRenderingException): with self.assertRaises(MarkdownRenderingError):
markdown_convert_wrapper(msg) markdown_convert_wrapper(msg)
def test_curl_code_block_validation(self) -> None: def test_curl_code_block_validation(self) -> None:
@ -2936,7 +2936,7 @@ class MarkdownErrorTests(ZulipTestCase):
"```", "```",
] ]
with self.assertRaises(MarkdownRenderingException): with self.assertRaises(MarkdownRenderingError):
processor.run(markdown_input) processor.run(markdown_input)
def test_curl_code_block_without_validation(self) -> None: def test_curl_code_block_without_validation(self) -> None:

View File

@ -28,7 +28,7 @@ from zerver.lib.message import (
) )
from zerver.lib.narrow import ( from zerver.lib.narrow import (
LARGER_THAN_MAX_MESSAGE_ID, LARGER_THAN_MAX_MESSAGE_ID,
BadNarrowOperator, BadNarrowOperatorError,
NarrowBuilder, NarrowBuilder,
build_narrow_filter, build_narrow_filter,
exclude_muting_conditions, exclude_muting_conditions,
@ -109,7 +109,7 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_not_defined_operator(self) -> None: def test_add_term_using_not_defined_operator(self) -> None:
term = dict(operator="not-defined", operand="any") term = dict(operator="not-defined", operand="any")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_stream_operator(self) -> None: def test_add_term_using_stream_operator(self) -> None:
term = dict(operator="stream", operand="Scotland") term = dict(operator="stream", operand="Scotland")
@ -123,7 +123,7 @@ class NarrowBuilderTest(ZulipTestCase):
self, self,
) -> None: # NEGATED ) -> None: # NEGATED
term = dict(operator="stream", operand="NonExistingStream") term = dict(operator="stream", operand="NonExistingStream")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_is_operator_and_private_operand(self) -> None: def test_add_term_using_is_operator_and_private_operand(self) -> None:
term = dict(operator="is", operand="private") term = dict(operator="is", operand="private")
@ -133,7 +133,7 @@ class NarrowBuilderTest(ZulipTestCase):
self, self,
) -> None: # NEGATED ) -> None: # NEGATED
term = dict(operator="streams", operand="invalid_operands") term = dict(operator="streams", operand="invalid_operands")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_streams_operator_and_public_stream_operand(self) -> None: def test_add_term_using_streams_operator_and_public_stream_operand(self) -> None:
term = dict(operator="streams", operand="public") term = dict(operator="streams", operand="public")
@ -261,7 +261,7 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_non_supported_operator_should_raise_error(self) -> None: def test_add_term_using_non_supported_operator_should_raise_error(self) -> None:
term = dict(operator="is", operand="non_supported") term = dict(operator="is", operand="non_supported")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_topic_operator_and_lunch_operand(self) -> None: def test_add_term_using_topic_operator_and_lunch_operand(self) -> None:
term = dict(operator="topic", operand="lunch") term = dict(operator="topic", operand="lunch")
@ -291,7 +291,7 @@ class NarrowBuilderTest(ZulipTestCase):
self, self,
) -> None: # NEGATED ) -> None: # NEGATED
term = dict(operator="sender", operand="non-existing@zulip.com") term = dict(operator="sender", operand="non-existing@zulip.com")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_pm_with_operator_and_not_the_same_user_as_operand(self) -> None: def test_add_term_using_pm_with_operator_and_not_the_same_user_as_operand(self) -> None:
term = dict(operator="pm-with", operand=self.othello_email) term = dict(operator="pm-with", operand=self.othello_email)
@ -375,13 +375,13 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_pm_with_operator_with_comma_noise(self) -> None: def test_add_term_using_pm_with_operator_with_comma_noise(self) -> None:
term = dict(operator="pm-with", operand=" ,,, ,,, ,") term = dict(operator="pm-with", operand=" ,,, ,,, ,")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_pm_with_operator_with_existing_and_non_existing_user_as_operand( def test_add_term_using_pm_with_operator_with_existing_and_non_existing_user_as_operand(
self, self,
) -> None: ) -> None:
term = dict(operator="pm-with", operand=self.othello_email + ",non-existing@zulip.com") term = dict(operator="pm-with", operand=self.othello_email + ",non-existing@zulip.com")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_id_operator(self) -> None: def test_add_term_using_id_operator(self) -> None:
term = dict(operator="id", operand=555) term = dict(operator="id", operand=555)
@ -389,10 +389,10 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_id_operator_invalid(self) -> None: def test_add_term_using_id_operator_invalid(self) -> None:
term = dict(operator="id", operand="") term = dict(operator="id", operand="")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
term = dict(operator="id", operand="notanint") term = dict(operator="id", operand="notanint")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_id_operator_and_negated(self) -> None: # NEGATED def test_add_term_using_id_operator_and_negated(self) -> None: # NEGATED
term = dict(operator="id", operand=555, negated=True) term = dict(operator="id", operand=555, negated=True)
@ -419,7 +419,7 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_group_pm_operator_with_non_existing_user_as_operand(self) -> None: def test_add_term_using_group_pm_operator_with_non_existing_user_as_operand(self) -> None:
term = dict(operator="group-pm-with", operand="non-existing@zulip.com") term = dict(operator="group-pm-with", operand="non-existing@zulip.com")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
@override_settings(USING_PGROONGA=False) @override_settings(USING_PGROONGA=False)
def test_add_term_using_search_operator(self) -> None: def test_add_term_using_search_operator(self) -> None:
@ -475,7 +475,7 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_has_operator_non_supported_operand_should_raise_error(self) -> None: def test_add_term_using_has_operator_non_supported_operand_should_raise_error(self) -> None:
term = dict(operator="has", operand="non_supported") term = dict(operator="has", operand="non_supported")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_in_operator(self) -> None: def test_add_term_using_in_operator(self) -> None:
mute_stream(self.realm, self.user_profile, "Verona") mute_stream(self.realm, self.user_profile, "Verona")
@ -503,7 +503,7 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_in_operator_and_not_defined_operand(self) -> None: def test_add_term_using_in_operator_and_not_defined_operand(self) -> None:
term = dict(operator="in", operand="not_defined") term = dict(operator="in", operand="not_defined")
self.assertRaises(BadNarrowOperator, self._build_query, term) self.assertRaises(BadNarrowOperatorError, self._build_query, term)
def test_add_term_using_near_operator(self) -> None: def test_add_term_using_near_operator(self) -> None:
term = dict(operator="near", operand="operand") term = dict(operator="near", operand="operand")
@ -518,7 +518,7 @@ class NarrowBuilderTest(ZulipTestCase):
def _build_query(term: Dict[str, Any]) -> Select: def _build_query(term: Dict[str, Any]) -> Select:
return builder.add_term(self.raw_query, term) return builder.add_term(self.raw_query, term)
self.assertRaises(BadNarrowOperator, _build_query, term) self.assertRaises(BadNarrowOperatorError, _build_query, term)
def _do_add_term_test( def _do_add_term_test(
self, term: Dict[str, Any], where_clause: str, params: Optional[Dict[str, Any]] = None self, term: Dict[str, Any], where_clause: str, params: Optional[Dict[str, Any]] = None

View File

@ -22,7 +22,7 @@ from zerver.lib.message import (
) )
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import get_subscription, timeout_mock from zerver.lib.test_helpers import get_subscription, timeout_mock
from zerver.lib.timeout import TimeoutExpired from zerver.lib.timeout import TimeoutExpiredError
from zerver.lib.user_topics import add_topic_mute from zerver.lib.user_topics import add_topic_mute
from zerver.models import ( from zerver.models import (
Message, Message,
@ -688,7 +688,7 @@ class MarkAllAsReadEndpointTest(ZulipTestCase):
def test_mark_all_as_read_timeout_response(self) -> None: def test_mark_all_as_read_timeout_response(self) -> None:
self.login("hamlet") self.login("hamlet")
with mock.patch("zerver.views.message_flags.timeout", side_effect=TimeoutExpired): with mock.patch("zerver.views.message_flags.timeout", side_effect=TimeoutExpiredError):
result = self.client_post("/json/mark_all_as_read", {}) result = self.client_post("/json/mark_all_as_read", {})
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)

View File

@ -63,7 +63,7 @@ from zerver.models import (
get_system_bot, get_system_bot,
get_user, get_user,
) )
from zerver.views.message_send import InvalidMirrorInput from zerver.views.message_send import InvalidMirrorInputError
if sys.version_info < (3, 9): # nocoverage if sys.version_info < (3, 9): # nocoverage
from backports import zoneinfo from backports import zoneinfo
@ -1098,7 +1098,7 @@ class MessagePOSTTest(ZulipTestCase):
def test_send_message_create_mirrored_message_user_returns_invalid_input( def test_send_message_create_mirrored_message_user_returns_invalid_input(
self, create_mirrored_message_users_mock: Any self, create_mirrored_message_users_mock: Any
) -> None: ) -> None:
create_mirrored_message_users_mock.side_effect = InvalidMirrorInput() create_mirrored_message_users_mock.side_effect = InvalidMirrorInputError()
result = self.api_post( result = self.api_post(
self.mit_user("starnine"), self.mit_user("starnine"),
"/api/v1/messages", "/api/v1/messages",

View File

@ -6,7 +6,7 @@ from django.utils.timezone import now as timezone_now
from zerver.actions.streams import do_change_stream_permission from zerver.actions.streams import do_change_stream_permission
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import timeout_mock from zerver.lib.test_helpers import timeout_mock
from zerver.lib.timeout import TimeoutExpired from zerver.lib.timeout import TimeoutExpiredError
from zerver.models import Message, UserMessage, get_client, get_realm, get_stream from zerver.models import Message, UserMessage, get_client, get_realm, get_stream
@ -322,7 +322,7 @@ class TopicDeleteTest(ZulipTestCase):
self.login_user(user_profile) self.login_user(user_profile)
endpoint = "/json/streams/" + str(stream.id) + "/delete_topic" endpoint = "/json/streams/" + str(stream.id) + "/delete_topic"
with mock.patch("zerver.views.streams.timeout", side_effect=TimeoutExpired): with mock.patch("zerver.views.streams.timeout", side_effect=TimeoutExpiredError):
result = self.client_post( result = self.client_post(
endpoint, endpoint,
{ {

View File

@ -9,7 +9,7 @@ from zerver.lib.create_user import create_user_profile
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import reset_emails_in_zulip_realm from zerver.lib.test_helpers import reset_emails_in_zulip_realm
from zerver.models import UserProfile, get_client, get_realm, get_user from zerver.models import UserProfile, get_client, get_realm, get_user
from zerver.views.message_send import InvalidMirrorInput, create_mirrored_message_users from zerver.views.message_send import InvalidMirrorInputError, create_mirrored_message_users
class MirroredMessageUsersTest(ZulipTestCase): class MirroredMessageUsersTest(ZulipTestCase):
@ -22,7 +22,7 @@ class MirroredMessageUsersTest(ZulipTestCase):
message_type = "private" message_type = "private"
client = get_client("banned_mirror") client = get_client("banned_mirror")
with self.assertRaises(InvalidMirrorInput): with self.assertRaises(InvalidMirrorInputError):
create_mirrored_message_users(client, user, recipients, sender.email, message_type) create_mirrored_message_users(client, user, recipients, sender.email, message_type)
def test_invalid_email(self) -> None: def test_invalid_email(self) -> None:
@ -38,7 +38,7 @@ class MirroredMessageUsersTest(ZulipTestCase):
for client_name in ["zephyr_mirror", "irc_mirror", "jabber_mirror"]: for client_name in ["zephyr_mirror", "irc_mirror", "jabber_mirror"]:
client = get_client(client_name) client = get_client(client_name)
with self.assertRaises(InvalidMirrorInput): with self.assertRaises(InvalidMirrorInputError):
create_mirrored_message_users(client, user, recipients, sender.email, message_type) create_mirrored_message_users(client, user, recipients, sender.email, message_type)
@mock.patch( @mock.patch(

View File

@ -49,7 +49,7 @@ from zerver.lib.push_notifications import (
send_notifications_to_bouncer, send_notifications_to_bouncer,
) )
from zerver.lib.remote_server import ( from zerver.lib.remote_server import (
PushNotificationBouncerException, PushNotificationBouncerError,
PushNotificationBouncerRetryLaterError, PushNotificationBouncerRetryLaterError,
build_analytics_data, build_analytics_data,
send_analytics_to_remote_server, send_analytics_to_remote_server,
@ -2220,7 +2220,7 @@ class TestSendToPushBouncer(ZulipTestCase):
# This is the exception our decorator uses for an invalid Zulip server # This is the exception our decorator uses for an invalid Zulip server
error_response = json_response_from_error(InvalidZulipServerError("testRole")) error_response = json_response_from_error(InvalidZulipServerError("testRole"))
self.add_mock_response(body=error_response.content, status=error_response.status_code) self.add_mock_response(body=error_response.content, status=error_response.status_code)
with self.assertRaises(PushNotificationBouncerException) as exc: with self.assertRaises(PushNotificationBouncerError) as exc:
send_to_push_bouncer("POST", "register", {"msg": "true"}) send_to_push_bouncer("POST", "register", {"msg": "true"})
self.assertEqual( self.assertEqual(
str(exc.exception), str(exc.exception),
@ -2237,7 +2237,7 @@ class TestSendToPushBouncer(ZulipTestCase):
@responses.activate @responses.activate
def test_300_error(self) -> None: def test_300_error(self) -> None:
self.add_mock_response(body=b"/", status=300) self.add_mock_response(body=b"/", status=300)
with self.assertRaises(PushNotificationBouncerException) as exc: with self.assertRaises(PushNotificationBouncerError) as exc:
send_to_push_bouncer("POST", "register", {"msg": "true"}) send_to_push_bouncer("POST", "register", {"msg": "true"})
self.assertEqual( self.assertEqual(
str(exc.exception), "Push notification bouncer returned unexpected status code 300" str(exc.exception), "Push notification bouncer returned unexpected status code 300"

View File

@ -17,9 +17,9 @@ from django.test import override_settings
from zerver.lib.email_mirror import RateLimitedRealmMirror from zerver.lib.email_mirror import RateLimitedRealmMirror
from zerver.lib.email_mirror_helpers import encode_email_address from zerver.lib.email_mirror_helpers import encode_email_address
from zerver.lib.queue import MAX_REQUEST_RETRIES from zerver.lib.queue import MAX_REQUEST_RETRIES
from zerver.lib.rate_limiter import RateLimiterLockingException from zerver.lib.rate_limiter import RateLimiterLockingError
from zerver.lib.remote_server import PushNotificationBouncerRetryLaterError from zerver.lib.remote_server import PushNotificationBouncerRetryLaterError
from zerver.lib.send_email import EmailNotDeliveredException, FromAddress from zerver.lib.send_email import EmailNotDeliveredError, FromAddress
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import mock_queue_publish from zerver.lib.test_helpers import mock_queue_publish
from zerver.models import ( from zerver.models import (
@ -507,10 +507,10 @@ class WorkerTest(ZulipTestCase):
worker.start() worker.start()
self.assertEqual(mock_mirror_email.call_count, 4) self.assertEqual(mock_mirror_email.call_count, 4)
# If RateLimiterLockingException is thrown, we rate-limit the new message: # If RateLimiterLockingError is thrown, we rate-limit the new message:
with patch( with patch(
"zerver.lib.rate_limiter.RedisRateLimiterBackend.incr_ratelimit", "zerver.lib.rate_limiter.RedisRateLimiterBackend.incr_ratelimit",
side_effect=RateLimiterLockingException, side_effect=RateLimiterLockingError,
): ):
with self.assertLogs("zerver.lib.rate_limiter", "WARNING") as mock_warn: with self.assertLogs("zerver.lib.rate_limiter", "WARNING") as mock_warn:
fake_client.enqueue("email_mirror", data[0]) fake_client.enqueue("email_mirror", data[0])
@ -553,14 +553,14 @@ class WorkerTest(ZulipTestCase):
worker = queue_processors.EmailSendingWorker() worker = queue_processors.EmailSendingWorker()
worker.setup() worker.setup()
with patch( with patch(
"zerver.lib.send_email.build_email", side_effect=EmailNotDeliveredException "zerver.lib.send_email.build_email", side_effect=EmailNotDeliveredError
), mock_queue_publish( ), mock_queue_publish(
"zerver.lib.queue.queue_json_publish", side_effect=fake_publish "zerver.lib.queue.queue_json_publish", side_effect=fake_publish
), self.assertLogs( ), self.assertLogs(
level="ERROR" level="ERROR"
) as m: ) as m:
worker.start() worker.start()
self.assertIn("failed due to exception EmailNotDeliveredException", m.output[0]) self.assertIn("failed due to exception EmailNotDeliveredError", m.output[0])
self.assertEqual(data["failed_tries"], 1 + MAX_REQUEST_RETRIES) self.assertEqual(data["failed_tries"], 1 + MAX_REQUEST_RETRIES)
@ -764,7 +764,7 @@ class WorkerTest(ZulipTestCase):
def consume(self, data: Mapping[str, Any]) -> None: def consume(self, data: Mapping[str, Any]) -> None:
pass # nocoverage # this is intentionally not called pass # nocoverage # this is intentionally not called
with self.assertRaises(queue_processors.WorkerDeclarationException): with self.assertRaises(queue_processors.WorkerDeclarationError):
TestWorker() TestWorker()
def test_get_active_worker_queues(self) -> None: def test_get_active_worker_queues(self) -> None:

View File

@ -6,7 +6,7 @@ from django.core.mail.backends.smtp import EmailBackend as SMTPBackend
from django.core.mail.message import sanitize_address from django.core.mail.message import sanitize_address
from zerver.lib.send_email import ( from zerver.lib.send_email import (
EmailNotDeliveredException, EmailNotDeliveredError,
FromAddress, FromAddress,
build_email, build_email,
initialize_connection, initialize_connection,
@ -118,7 +118,7 @@ class TestSendEmail(ZulipTestCase):
) )
self.assertEqual(mail.extra_headers["From"], f"{from_name} <{FromAddress.NOREPLY}>") self.assertEqual(mail.extra_headers["From"], f"{from_name} <{FromAddress.NOREPLY}>")
# We test the cases that should raise an EmailNotDeliveredException # We test the cases that should raise an EmailNotDeliveredError
errors = { errors = {
f"Unknown error sending password_reset email to {mail.to}": [0], f"Unknown error sending password_reset email to {mail.to}": [0],
f"Error sending password_reset email to {mail.to}": [SMTPException()], f"Error sending password_reset email to {mail.to}": [SMTPException()],
@ -133,7 +133,7 @@ class TestSendEmail(ZulipTestCase):
for message, side_effect in errors.items(): for message, side_effect in errors.items():
with mock.patch.object(EmailBackend, "send_messages", side_effect=side_effect): with mock.patch.object(EmailBackend, "send_messages", side_effect=side_effect):
with self.assertLogs(logger=logger) as info_log: with self.assertLogs(logger=logger) as info_log:
with self.assertRaises(EmailNotDeliveredException): with self.assertRaises(EmailNotDeliveredError):
send_email( send_email(
"zerver/emails/password_reset", "zerver/emails/password_reset",
to_emails=[hamlet.email], to_emails=[hamlet.email],

View File

@ -10,7 +10,7 @@ from typing_extensions import Concatenate, ParamSpec
from zerver.actions.create_user import do_create_user from zerver.actions.create_user import do_create_user
from zerver.actions.message_send import get_service_bot_events from zerver.actions.message_send import get_service_bot_events
from zerver.lib.bot_config import ConfigError, load_bot_config_template, set_bot_config from zerver.lib.bot_config import ConfigError, load_bot_config_template, set_bot_config
from zerver.lib.bot_lib import EmbeddedBotEmptyRecipientsList, EmbeddedBotHandler, StateHandler from zerver.lib.bot_lib import EmbeddedBotEmptyRecipientsListError, EmbeddedBotHandler, StateHandler
from zerver.lib.bot_storage import StateError from zerver.lib.bot_storage import StateError
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import mock_queue_publish from zerver.lib.test_helpers import mock_queue_publish
@ -409,7 +409,7 @@ class TestServiceBotConfigHandler(ZulipTestCase):
def test_bot_send_pm_with_empty_recipients_list(self) -> None: def test_bot_send_pm_with_empty_recipients_list(self) -> None:
with self.assertRaisesRegex( with self.assertRaisesRegex(
EmbeddedBotEmptyRecipientsList, "Message must have recipients!" EmbeddedBotEmptyRecipientsListError, "Message must have recipients!"
): ):
self.bot_handler.send_message(message={"type": "private", "to": []}) self.bot_handler.send_message(message={"type": "private", "to": []})

View File

@ -23,7 +23,7 @@ from django.utils.translation import gettext as _
from confirmation import settings as confirmation_settings from confirmation import settings as confirmation_settings
from confirmation.models import ( from confirmation.models import (
Confirmation, Confirmation,
ConfirmationKeyException, ConfirmationKeyError,
create_confirmation_link, create_confirmation_link,
get_object_from_key, get_object_from_key,
one_click_unsubscribe_link, one_click_unsubscribe_link,
@ -67,7 +67,7 @@ from zerver.lib.mobile_auth_otp import (
from zerver.lib.name_restrictions import is_disposable_domain from zerver.lib.name_restrictions import is_disposable_domain
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
from zerver.lib.send_email import ( from zerver.lib.send_email import (
EmailNotDeliveredException, EmailNotDeliveredError,
FromAddress, FromAddress,
deliver_scheduled_emails, deliver_scheduled_emails,
send_future_email, send_future_email,
@ -2160,9 +2160,9 @@ so we didn't send them an invitation. We did send invitations to everyone else!"
registration_key = url.split("/")[-1] registration_key = url.split("/")[-1]
# Mainly a test of get_object_from_key, rather than of the invitation pathway # Mainly a test of get_object_from_key, rather than of the invitation pathway
with self.assertRaises(ConfirmationKeyException) as cm: with self.assertRaises(ConfirmationKeyError) as cm:
get_object_from_key(registration_key, [Confirmation.INVITATION], mark_object_used=True) get_object_from_key(registration_key, [Confirmation.INVITATION], mark_object_used=True)
self.assertEqual(cm.exception.error_type, ConfirmationKeyException.DOES_NOT_EXIST) self.assertEqual(cm.exception.error_type, ConfirmationKeyError.DOES_NOT_EXIST)
# Verify that using the wrong type doesn't work in the main confirm code path # Verify that using the wrong type doesn't work in the main confirm code path
email_change_url = create_confirmation_link(prereg_user, Confirmation.EMAIL_CHANGE) email_change_url = create_confirmation_link(prereg_user, Confirmation.EMAIL_CHANGE)
@ -4093,13 +4093,13 @@ class UserSignUpTest(InviteUserBase):
def test_bad_email_configuration_for_accounts_home(self) -> None: def test_bad_email_configuration_for_accounts_home(self) -> None:
""" """
Make sure we redirect for EmailNotDeliveredException. Make sure we redirect for EmailNotDeliveredError.
""" """
email = self.nonreg_email("newguy") email = self.nonreg_email("newguy")
smtp_mock = patch( smtp_mock = patch(
"zerver.views.registration.send_confirm_registration_email", "zerver.views.registration.send_confirm_registration_email",
side_effect=EmailNotDeliveredException, side_effect=EmailNotDeliveredError,
) )
with smtp_mock, self.assertLogs(level="ERROR") as m: with smtp_mock, self.assertLogs(level="ERROR") as m:
@ -4110,13 +4110,13 @@ class UserSignUpTest(InviteUserBase):
def test_bad_email_configuration_for_create_realm(self) -> None: def test_bad_email_configuration_for_create_realm(self) -> None:
""" """
Make sure we redirect for EmailNotDeliveredException. Make sure we redirect for EmailNotDeliveredError.
""" """
email = self.nonreg_email("newguy") email = self.nonreg_email("newguy")
smtp_mock = patch( smtp_mock = patch(
"zerver.views.registration.send_confirm_registration_email", "zerver.views.registration.send_confirm_registration_email",
side_effect=EmailNotDeliveredException, side_effect=EmailNotDeliveredError,
) )
with smtp_mock, self.assertLogs(level="ERROR") as m: with smtp_mock, self.assertLogs(level="ERROR") as m:

View File

@ -1,6 +1,6 @@
from django.template.loader import get_template from django.template.loader import get_template
from zerver.lib.exceptions import InvalidMarkdownIncludeStatement from zerver.lib.exceptions import InvalidMarkdownIncludeStatementError
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
@ -123,7 +123,7 @@ footer
} }
with self.assertRaisesRegex( with self.assertRaisesRegex(
InvalidMarkdownIncludeStatement, "Invalid Markdown include statement" InvalidMarkdownIncludeStatementError, "Invalid Markdown include statement"
): ):
template.render(context) template.render(context)

View File

@ -2,7 +2,7 @@ import time
import traceback import traceback
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timeout import TimeoutExpired, timeout from zerver.lib.timeout import TimeoutExpiredError, timeout
class TimeoutTestCase(ZulipTestCase): class TimeoutTestCase(ZulipTestCase):
@ -25,7 +25,7 @@ class TimeoutTestCase(ZulipTestCase):
try: try:
timeout(1, lambda: self.sleep_x_seconds_y_times(0.1, 50)) timeout(1, lambda: self.sleep_x_seconds_y_times(0.1, 50))
raise AssertionError("Failed to raise a timeout") raise AssertionError("Failed to raise a timeout")
except TimeoutExpired as exc: except TimeoutExpiredError as exc:
tb = traceback.format_tb(exc.__traceback__) tb = traceback.format_tb(exc.__traceback__)
self.assertIn("in sleep_x_seconds_y_times", tb[-1]) self.assertIn("in sleep_x_seconds_y_times", tb[-1])
self.assertIn("time.sleep(x)", tb[-1]) self.assertIn("time.sleep(x)", tb[-1])
@ -46,8 +46,8 @@ class TimeoutTestCase(ZulipTestCase):
try: try:
timeout(1, lambda: self.sleep_x_seconds_y_times(5, 1)) timeout(1, lambda: self.sleep_x_seconds_y_times(5, 1))
raise AssertionError("Failed to raise a timeout") raise AssertionError("Failed to raise a timeout")
except TimeoutExpired as exc: except TimeoutExpiredError as exc:
tb = traceback.format_tb(exc.__traceback__) tb = traceback.format_tb(exc.__traceback__)
self.assertNotIn("in sleep_x_seconds_y_times", tb[-1]) self.assertNotIn("in sleep_x_seconds_y_times", tb[-1])
self.assertIn("raise TimeoutExpired", tb[-1]) self.assertIn("raise TimeoutExpiredError", tb[-1])
self.assertEqual(m.output, ["WARNING:root:Failed to time out backend thread"]) self.assertEqual(m.output, ["WARNING:root:Failed to time out backend thread"])

View File

@ -4,7 +4,7 @@ from dateutil import parser
from zerver.lib.test_classes import ZulipTestCase from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timestamp import ( from zerver.lib.timestamp import (
TimeZoneNotUTCException, TimeZoneNotUTCError,
ceiling_to_hour, ceiling_to_hour,
convert_to_UTC, convert_to_UTC,
datetime_to_timestamp, datetime_to_timestamp,
@ -28,7 +28,7 @@ class TestTimestamp(ZulipTestCase):
parser.parse("2017-01-01 00:00:00.123+01:00"), parser.parse("2017-01-01 00:00:00.123+01:00"),
parser.parse("2017-01-01 00:00:00.123"), parser.parse("2017-01-01 00:00:00.123"),
]: ]:
with self.assertRaises(TimeZoneNotUTCException): with self.assertRaises(TimeZoneNotUTCError):
datetime_to_timestamp(dt) datetime_to_timestamp(dt)
def test_convert_to_UTC(self) -> None: def test_convert_to_UTC(self) -> None:
@ -43,5 +43,5 @@ class TestTimestamp(ZulipTestCase):
def test_enforce_UTC(self) -> None: def test_enforce_UTC(self) -> None:
non_utc_datetime = parser.parse("2017-01-01 00:00:00.123") non_utc_datetime = parser.parse("2017-01-01 00:00:00.123")
for function in [floor_to_hour, floor_to_day, ceiling_to_hour, ceiling_to_hour]: for function in [floor_to_hour, floor_to_day, ceiling_to_hour, ceiling_to_hour]:
with self.assertRaises(TimeZoneNotUTCException): with self.assertRaises(TimeZoneNotUTCError):
function(non_utc_datetime) function(non_utc_datetime)

View File

@ -51,7 +51,7 @@ from zerver.lib.users import Accounts, access_user_by_id, get_accounts_for_email
from zerver.lib.utils import assert_is_not_none from zerver.lib.utils import assert_is_not_none
from zerver.models import ( from zerver.models import (
CustomProfileField, CustomProfileField,
InvalidFakeEmailDomain, InvalidFakeEmailDomainError,
Message, Message,
PreregistrationUser, PreregistrationUser,
Realm, Realm,
@ -2304,12 +2304,12 @@ class FakeEmailDomainTest(ZulipTestCase):
@override_settings(FAKE_EMAIL_DOMAIN="invaliddomain", REALM_HOSTS={"zulip": "127.0.0.1"}) @override_settings(FAKE_EMAIL_DOMAIN="invaliddomain", REALM_HOSTS={"zulip": "127.0.0.1"})
def test_invalid_fake_email_domain(self) -> None: def test_invalid_fake_email_domain(self) -> None:
realm = get_realm("zulip") realm = get_realm("zulip")
with self.assertRaises(InvalidFakeEmailDomain): with self.assertRaises(InvalidFakeEmailDomainError):
get_fake_email_domain(realm) get_fake_email_domain(realm)
@override_settings(FAKE_EMAIL_DOMAIN="127.0.0.1", REALM_HOSTS={"zulip": "127.0.0.1"}) @override_settings(FAKE_EMAIL_DOMAIN="127.0.0.1", REALM_HOSTS={"zulip": "127.0.0.1"})
def test_invalid_fake_email_domain_ip(self) -> None: def test_invalid_fake_email_domain_ip(self) -> None:
with self.assertRaises(InvalidFakeEmailDomain): with self.assertRaises(InvalidFakeEmailDomainError):
realm = get_realm("zulip") realm = get_realm("zulip")
get_fake_email_domain(realm) get_fake_email_domain(realm)

View File

@ -15,7 +15,7 @@ from zerver.lib.users import get_api_key
from zerver.lib.webhooks.common import ( from zerver.lib.webhooks.common import (
INVALID_JSON_MESSAGE, INVALID_JSON_MESSAGE,
MISSING_EVENT_HEADER_MESSAGE, MISSING_EVENT_HEADER_MESSAGE,
MissingHTTPEventHeader, MissingHTTPEventHeaderError,
get_fixture_http_headers, get_fixture_http_headers,
standardize_headers, standardize_headers,
validate_extract_webhook_http_header, validate_extract_webhook_http_header,
@ -46,7 +46,7 @@ class WebhooksCommonTestCase(ZulipTestCase):
request.path = "some/random/path" request.path = "some/random/path"
exception_msg = "Missing the HTTP event header 'X-Custom-Header'" exception_msg = "Missing the HTTP event header 'X-Custom-Header'"
with self.assertRaisesRegex(MissingHTTPEventHeader, exception_msg): with self.assertRaisesRegex(MissingHTTPEventHeaderError, exception_msg):
validate_extract_webhook_http_header(request, "X-Custom-Header", "test_webhook") validate_extract_webhook_http_header(request, "X-Custom-Header", "test_webhook")
msg = self.get_last_message() msg = self.get_last_message()

View File

@ -33,7 +33,7 @@ from typing_extensions import Concatenate, ParamSpec
from confirmation.models import ( from confirmation.models import (
Confirmation, Confirmation,
ConfirmationKeyException, ConfirmationKeyError,
create_confirmation_link, create_confirmation_link,
get_object_from_key, get_object_from_key,
render_confirmation_key_error, render_confirmation_key_error,
@ -54,7 +54,7 @@ from zerver.lib.exceptions import (
JsonableError, JsonableError,
PasswordAuthDisabledError, PasswordAuthDisabledError,
PasswordResetRequiredError, PasswordResetRequiredError,
RateLimited, RateLimitedError,
RealmDeactivatedError, RealmDeactivatedError,
UserDeactivatedError, UserDeactivatedError,
) )
@ -200,7 +200,7 @@ def maybe_send_to_registration(
confirmation_obj = get_object_from_key( confirmation_obj = get_object_from_key(
multiuse_object_key, [Confirmation.MULTIUSE_INVITE], mark_object_used=False multiuse_object_key, [Confirmation.MULTIUSE_INVITE], mark_object_used=False
) )
except ConfirmationKeyException as exception: except ConfirmationKeyError as exception:
return render_confirmation_key_error(request, exception) return render_confirmation_key_error(request, exception)
assert isinstance(confirmation_obj, MultiuseInvite) assert isinstance(confirmation_obj, MultiuseInvite)
@ -1037,7 +1037,7 @@ def password_reset(request: HttpRequest) -> HttpResponse:
form_class=ZulipPasswordResetForm, form_class=ZulipPasswordResetForm,
success_url="/accounts/password/reset/done/", success_url="/accounts/password/reset/done/",
)(request) )(request)
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
return render( return render(
request, request,

View File

@ -15,7 +15,7 @@ from zerver.actions.invites import (
do_revoke_user_invite, do_revoke_user_invite,
) )
from zerver.decorator import require_member_or_admin, require_realm_admin from zerver.decorator import require_member_or_admin, require_realm_admin
from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequired from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequiredError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.streams import access_stream_by_id from zerver.lib.streams import access_stream_by_id
@ -34,7 +34,7 @@ def check_if_owner_required(invited_as: int, user_profile: UserProfile) -> None:
invited_as == PreregistrationUser.INVITE_AS["REALM_OWNER"] invited_as == PreregistrationUser.INVITE_AS["REALM_OWNER"]
and not user_profile.is_realm_owner and not user_profile.is_realm_owner
): ):
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
@require_member_or_admin @require_member_or_admin

View File

@ -18,7 +18,7 @@ from zerver.lib.narrow import (
from zerver.lib.request import REQ, RequestNotes, has_request_variables from zerver.lib.request import REQ, RequestNotes, has_request_variables
from zerver.lib.response import json_partial_success, json_success from zerver.lib.response import json_partial_success, json_success
from zerver.lib.streams import access_stream_by_id from zerver.lib.streams import access_stream_by_id
from zerver.lib.timeout import TimeoutExpired, timeout from zerver.lib.timeout import TimeoutExpiredError, timeout
from zerver.lib.topic import user_message_exists_for_topic from zerver.lib.topic import user_message_exists_for_topic
from zerver.lib.validator import check_bool, check_int, check_list, to_non_negative_int from zerver.lib.validator import check_bool, check_int, check_list, to_non_negative_int
from zerver.models import UserActivity, UserProfile from zerver.models import UserActivity, UserProfile
@ -121,7 +121,7 @@ def mark_all_as_read(request: HttpRequest, user_profile: UserProfile) -> HttpRes
request_notes = RequestNotes.get_notes(request) request_notes = RequestNotes.get_notes(request)
try: try:
count = timeout(50, lambda: do_mark_all_as_read(user_profile)) count = timeout(50, lambda: do_mark_all_as_read(user_profile))
except TimeoutExpired: except TimeoutExpiredError:
return json_partial_success(request, data={"code": ErrorCode.REQUEST_TIMEOUT.name}) return json_partial_success(request, data={"code": ErrorCode.REQUEST_TIMEOUT.name})
log_data_str = f"[{count} updated]" log_data_str = f"[{count} updated]"

View File

@ -42,7 +42,7 @@ else: # nocoverage
import zoneinfo import zoneinfo
class InvalidMirrorInput(Exception): class InvalidMirrorInputError(Exception):
pass pass
@ -70,12 +70,12 @@ def create_mirrored_message_users(
user_check = same_realm_jabber_user user_check = same_realm_jabber_user
fullname_function = compute_jabber_user_fullname fullname_function = compute_jabber_user_fullname
else: else:
raise InvalidMirrorInput("Unrecognized mirroring client") raise InvalidMirrorInputError("Unrecognized mirroring client")
for email in referenced_users: for email in referenced_users:
# Check that all referenced users are in our realm: # Check that all referenced users are in our realm:
if not user_check(user_profile, email): if not user_check(user_profile, email):
raise InvalidMirrorInput("At least one user cannot be mirrored") raise InvalidMirrorInputError("At least one user cannot be mirrored")
# Create users for the referenced users, if needed. # Create users for the referenced users, if needed.
for email in referenced_users: for email in referenced_users:
@ -278,7 +278,7 @@ def send_message_backend(
mirror_sender = create_mirrored_message_users( mirror_sender = create_mirrored_message_users(
client, user_profile, message_to, req_sender, message_type_name client, user_profile, message_to, req_sender, message_type_name
) )
except InvalidMirrorInput: except InvalidMirrorInputError:
raise JsonableError(_("Invalid mirrored message")) raise JsonableError(_("Invalid mirrored message"))
if client.name == "zephyr_mirror" and not user_profile.realm.is_zephyr_mirror_realm: if client.name == "zephyr_mirror" and not user_profile.realm.is_zephyr_mirror_realm:

View File

@ -6,7 +6,7 @@ from django.shortcuts import render
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.decorators.http import require_safe from django.views.decorators.http import require_safe
from confirmation.models import Confirmation, ConfirmationKeyException, get_object_from_key from confirmation.models import Confirmation, ConfirmationKeyError, get_object_from_key
from zerver.actions.create_realm import do_change_realm_subdomain from zerver.actions.create_realm import do_change_realm_subdomain
from zerver.actions.realm_settings import ( from zerver.actions.realm_settings import (
do_change_realm_org_type, do_change_realm_org_type,
@ -20,7 +20,7 @@ from zerver.actions.realm_settings import (
) )
from zerver.decorator import require_realm_admin, require_realm_owner from zerver.decorator import require_realm_admin, require_realm_owner
from zerver.forms import check_subdomain_available as check_subdomain from zerver.forms import check_subdomain_available as check_subdomain
from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequired from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequiredError
from zerver.lib.i18n import get_available_language_codes from zerver.lib.i18n import get_available_language_codes
from zerver.lib.message import parse_message_content_edit_or_delete_limit from zerver.lib.message import parse_message_content_edit_or_delete_limit
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
@ -155,7 +155,7 @@ def update_realm(
raise JsonableError(_("Invalid language '{}'").format(default_language)) raise JsonableError(_("Invalid language '{}'").format(default_language))
if authentication_methods is not None: if authentication_methods is not None:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if True not in list(authentication_methods.values()): if True not in list(authentication_methods.values()):
raise JsonableError(_("At least one authentication method must be enabled.")) raise JsonableError(_("At least one authentication method must be enabled."))
if video_chat_provider is not None and video_chat_provider not in { if video_chat_provider is not None and video_chat_provider not in {
@ -170,7 +170,7 @@ def update_realm(
message_retention_days: Optional[int] = None message_retention_days: Optional[int] = None
if message_retention_days_raw is not None: if message_retention_days_raw is not None:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
realm.ensure_not_on_limited_plan() realm.ensure_not_on_limited_plan()
message_retention_days = parse_message_retention_days( message_retention_days = parse_message_retention_days(
message_retention_days_raw, Realm.MESSAGE_RETENTION_SPECIAL_VALUES_MAP message_retention_days_raw, Realm.MESSAGE_RETENTION_SPECIAL_VALUES_MAP
@ -180,15 +180,15 @@ def update_realm(
if ( if (
invite_to_realm_policy is not None or invite_required is not None invite_to_realm_policy is not None or invite_required is not None
) and not user_profile.is_realm_owner: ) and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if ( if (
emails_restricted_to_domains is not None or disallow_disposable_email_addresses is not None emails_restricted_to_domains is not None or disallow_disposable_email_addresses is not None
) and not user_profile.is_realm_owner: ) and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if waiting_period_threshold is not None and not user_profile.is_realm_owner: if waiting_period_threshold is not None and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if enable_spectator_access: if enable_spectator_access:
realm.ensure_not_on_limited_plan() realm.ensure_not_on_limited_plan()
@ -307,7 +307,7 @@ def update_realm(
if string_id is not None: if string_id is not None:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if realm.demo_organization_scheduled_deletion_date is None: if realm.demo_organization_scheduled_deletion_date is None:
raise JsonableError(_("Must be a demo organization.")) raise JsonableError(_("Must be a demo organization."))
@ -349,7 +349,7 @@ def realm_reactivation(request: HttpRequest, confirmation_key: str) -> HttpRespo
obj = get_object_from_key( obj = get_object_from_key(
confirmation_key, [Confirmation.REALM_REACTIVATION], mark_object_used=True confirmation_key, [Confirmation.REALM_REACTIVATION], mark_object_used=True
) )
except ConfirmationKeyException: except ConfirmationKeyError:
return render(request, "zerver/realm_reactivation_link_error.html", status=404) return render(request, "zerver/realm_reactivation_link_error.html", status=404)
assert isinstance(obj, RealmReactivationStatus) assert isinstance(obj, RealmReactivationStatus)

View File

@ -17,7 +17,7 @@ from django_auth_ldap.backend import LDAPBackend, _LDAPUser
from confirmation.models import ( from confirmation.models import (
Confirmation, Confirmation,
ConfirmationKeyException, ConfirmationKeyError,
RealmCreationKey, RealmCreationKey,
create_confirmation_link, create_confirmation_link,
get_object_from_key, get_object_from_key,
@ -42,12 +42,12 @@ from zerver.forms import (
RegistrationForm, RegistrationForm,
) )
from zerver.lib.email_validation import email_allowed_for_realm, validate_email_not_already_in_realm from zerver.lib.email_validation import email_allowed_for_realm, validate_email_not_already_in_realm
from zerver.lib.exceptions import RateLimited from zerver.lib.exceptions import RateLimitedError
from zerver.lib.i18n import get_default_language_for_new_user from zerver.lib.i18n import get_default_language_for_new_user
from zerver.lib.pysa import mark_sanitized from zerver.lib.pysa import mark_sanitized
from zerver.lib.rate_limiter import rate_limit_request_by_ip from zerver.lib.rate_limiter import rate_limit_request_by_ip
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.send_email import EmailNotDeliveredException, FromAddress, send_email from zerver.lib.send_email import EmailNotDeliveredError, FromAddress, send_email
from zerver.lib.sessions import get_expirable_session_var from zerver.lib.sessions import get_expirable_session_var
from zerver.lib.subdomains import get_subdomain, is_root_domain_available from zerver.lib.subdomains import get_subdomain, is_root_domain_available
from zerver.lib.url_encoding import append_url_query_string from zerver.lib.url_encoding import append_url_query_string
@ -79,8 +79,8 @@ from zerver.views.auth import (
) )
from zproject.backends import ( from zproject.backends import (
ExternalAuthResult, ExternalAuthResult,
NoMatchingLDAPUserError,
ZulipLDAPAuthBackend, ZulipLDAPAuthBackend,
ZulipLDAPExceptionNoMatchingLDAPUser,
email_auth_enabled, email_auth_enabled,
email_belongs_to_ldap, email_belongs_to_ldap,
get_external_method_dicts, get_external_method_dicts,
@ -114,7 +114,7 @@ def get_prereg_key_and_redirect(
""" """
try: try:
check_prereg_key(request, confirmation_key) check_prereg_key(request, confirmation_key)
except ConfirmationKeyException as e: except ConfirmationKeyError as e:
return render_confirmation_key_error(request, e) return render_confirmation_key_error(request, e)
return render( return render(
@ -127,7 +127,7 @@ def get_prereg_key_and_redirect(
def check_prereg_key(request: HttpRequest, confirmation_key: str) -> PreregistrationUser: def check_prereg_key(request: HttpRequest, confirmation_key: str) -> PreregistrationUser:
""" """
Checks if the Confirmation key is valid, returning the PreregistrationUser object in case of success Checks if the Confirmation key is valid, returning the PreregistrationUser object in case of success
and raising an appropriate ConfirmationKeyException otherwise. and raising an appropriate ConfirmationKeyError otherwise.
""" """
confirmation_types = [ confirmation_types = [
Confirmation.USER_REGISTRATION, Confirmation.USER_REGISTRATION,
@ -159,7 +159,7 @@ def accounts_register(
) -> HttpResponse: ) -> HttpResponse:
try: try:
prereg_user = check_prereg_key(request, key) prereg_user = check_prereg_key(request, key)
except ConfirmationKeyException as e: except ConfirmationKeyError as e:
return render_confirmation_key_error(request, e) return render_confirmation_key_error(request, e)
email = prereg_user.email email = prereg_user.email
@ -182,7 +182,7 @@ def accounts_register(
assert prereg_user.realm is not None assert prereg_user.realm is not None
if get_subdomain(request) != prereg_user.realm.string_id: if get_subdomain(request) != prereg_user.realm.string_id:
return render_confirmation_key_error( return render_confirmation_key_error(
request, ConfirmationKeyException(ConfirmationKeyException.DOES_NOT_EXIST) request, ConfirmationKeyError(ConfirmationKeyError.DOES_NOT_EXIST)
) )
realm = prereg_user.realm realm = prereg_user.realm
try: try:
@ -239,7 +239,7 @@ def accounts_register(
if isinstance(backend, LDAPBackend): if isinstance(backend, LDAPBackend):
try: try:
ldap_username = backend.django_to_ldap_username(email) ldap_username = backend.django_to_ldap_username(email)
except ZulipLDAPExceptionNoMatchingLDAPUser: except NoMatchingLDAPUserError:
logging.warning("New account email %s could not be found in LDAP", email) logging.warning("New account email %s could not be found in LDAP", email)
break break
@ -607,7 +607,7 @@ def redirect_to_email_login_url(email: str) -> HttpResponseRedirect:
def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> HttpResponse: def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> HttpResponse:
try: try:
key_record = validate_key(creation_key) key_record = validate_key(creation_key)
except RealmCreationKey.Invalid: except RealmCreationKey.InvalidError:
return render( return render(
request, request,
"zerver/realm_creation_link_invalid.html", "zerver/realm_creation_link_invalid.html",
@ -626,7 +626,7 @@ def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> Ht
if form.is_valid(): if form.is_valid():
try: try:
rate_limit_request_by_ip(request, domain="sends_email_by_ip") rate_limit_request_by_ip(request, domain="sends_email_by_ip")
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
return render( return render(
request, request,
@ -649,7 +649,7 @@ def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> Ht
try: try:
send_confirm_registration_email(email, activation_url, request=request) send_confirm_registration_email(email, activation_url, request=request)
except EmailNotDeliveredException: except EmailNotDeliveredError:
logging.error("Error in create_realm") logging.error("Error in create_realm")
return HttpResponseRedirect("/config-error/smtp") return HttpResponseRedirect("/config-error/smtp")
@ -701,7 +701,7 @@ def accounts_home(
if form.is_valid(): if form.is_valid():
try: try:
rate_limit_request_by_ip(request, domain="sends_email_by_ip") rate_limit_request_by_ip(request, domain="sends_email_by_ip")
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
return render( return render(
request, request,
@ -727,7 +727,7 @@ def accounts_home(
) )
try: try:
send_confirm_registration_email(email, activation_url, request=request, realm=realm) send_confirm_registration_email(email, activation_url, request=request, realm=realm)
except EmailNotDeliveredException: except EmailNotDeliveredError:
logging.error("Error in accounts_home") logging.error("Error in accounts_home")
return HttpResponseRedirect("/config-error/smtp") return HttpResponseRedirect("/config-error/smtp")
@ -757,7 +757,7 @@ def accounts_home_from_multiuse_invite(request: HttpRequest, confirmation_key: s
if realm != multiuse_object.realm: if realm != multiuse_object.realm:
return render(request, "confirmation/link_does_not_exist.html", status=404) return render(request, "confirmation/link_does_not_exist.html", status=404)
# Required for OAuth 2 # Required for OAuth 2
except ConfirmationKeyException as exception: except ConfirmationKeyError as exception:
if realm is None or realm.invite_required: if realm is None or realm.invite_required:
return render_confirmation_key_error(request, exception) return render_confirmation_key_error(request, exception)
return accounts_home( return accounts_home(
@ -779,7 +779,7 @@ def find_account(
for i in range(len(emails)): for i in range(len(emails)):
try: try:
rate_limit_request_by_ip(request, domain="sends_email_by_ip") rate_limit_request_by_ip(request, domain="sends_email_by_ip")
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
return render( return render(
request, request,

View File

@ -49,7 +49,7 @@ from zerver.decorator import (
from zerver.lib.exceptions import ( from zerver.lib.exceptions import (
ErrorCode, ErrorCode,
JsonableError, JsonableError,
OrganizationOwnerRequired, OrganizationOwnerRequiredError,
ResourceNotFoundError, ResourceNotFoundError,
) )
from zerver.lib.mention import MentionBackend, silent_mention_syntax_for_user from zerver.lib.mention import MentionBackend, silent_mention_syntax_for_user
@ -72,7 +72,7 @@ from zerver.lib.streams import (
) )
from zerver.lib.string_validation import check_stream_name from zerver.lib.string_validation import check_stream_name
from zerver.lib.subscription_info import gather_subscriptions from zerver.lib.subscription_info import gather_subscriptions
from zerver.lib.timeout import TimeoutExpired, timeout from zerver.lib.timeout import TimeoutExpiredError, timeout
from zerver.lib.topic import ( from zerver.lib.topic import (
get_topic_history_for_public_stream, get_topic_history_for_public_stream,
get_topic_history_for_stream, get_topic_history_for_stream,
@ -346,7 +346,7 @@ def update_stream_backend(
if message_retention_days is not None: if message_retention_days is not None:
if not user_profile.is_realm_owner: if not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
user_profile.realm.ensure_not_on_limited_plan() user_profile.realm.ensure_not_on_limited_plan()
new_message_retention_days_value = parse_message_retention_days( new_message_retention_days_value = parse_message_retention_days(
message_retention_days, Stream.MESSAGE_RETENTION_SPECIAL_VALUES_MAP message_retention_days, Stream.MESSAGE_RETENTION_SPECIAL_VALUES_MAP
@ -889,7 +889,7 @@ def delete_in_topic(
try: try:
timeout(50, delete_in_batches) timeout(50, delete_in_batches)
except TimeoutExpired: except TimeoutExpiredError:
return json_partial_success(request, data={"code": ErrorCode.REQUEST_TIMEOUT.name}) return json_partial_success(request, data={"code": ErrorCode.REQUEST_TIMEOUT.name})
return json_success(request) return json_success(request)

View File

@ -4,7 +4,7 @@ from django.http import HttpRequest, HttpResponse
from django.shortcuts import render from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from confirmation.models import Confirmation, ConfirmationKeyException, get_object_from_key from confirmation.models import Confirmation, ConfirmationKeyError, get_object_from_key
from zerver.actions.user_settings import do_change_user_setting from zerver.actions.user_settings import do_change_user_setting
from zerver.context_processors import common_context from zerver.context_processors import common_context
from zerver.lib.send_email import clear_scheduled_emails from zerver.lib.send_email import clear_scheduled_emails
@ -21,7 +21,7 @@ def process_unsubscribe(
user_profile = get_object_from_key( user_profile = get_object_from_key(
confirmation_key, [Confirmation.UNSUBSCRIBE], mark_object_used=False confirmation_key, [Confirmation.UNSUBSCRIBE], mark_object_used=False
) )
except ConfirmationKeyException: except ConfirmationKeyError:
return render(request, "zerver/unsubscribe_link_error.html") return render(request, "zerver/unsubscribe_link_error.html")
assert isinstance(user_profile, UserProfile) assert isinstance(user_profile, UserProfile)

View File

@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy
from confirmation.models import ( from confirmation.models import (
Confirmation, Confirmation,
ConfirmationKeyException, ConfirmationKeyError,
get_object_from_key, get_object_from_key,
render_confirmation_key_error, render_confirmation_key_error,
) )
@ -33,7 +33,7 @@ from zerver.lib.email_validation import (
validate_email_is_valid, validate_email_is_valid,
validate_email_not_already_in_realm, validate_email_not_already_in_realm,
) )
from zerver.lib.exceptions import JsonableError, RateLimited, UserDeactivatedError from zerver.lib.exceptions import JsonableError, RateLimitedError, UserDeactivatedError
from zerver.lib.i18n import get_available_language_codes from zerver.lib.i18n import get_available_language_codes
from zerver.lib.rate_limiter import RateLimitedUser from zerver.lib.rate_limiter import RateLimitedUser
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
@ -65,7 +65,7 @@ def confirm_email_change(request: HttpRequest, confirmation_key: str) -> HttpRes
email_change_object = get_object_from_key( email_change_object = get_object_from_key(
confirmation_key, [Confirmation.EMAIL_CHANGE], mark_object_used=True confirmation_key, [Confirmation.EMAIL_CHANGE], mark_object_used=True
) )
except ConfirmationKeyException as exception: except ConfirmationKeyError as exception:
return render_confirmation_key_error(request, exception) return render_confirmation_key_error(request, exception)
assert isinstance(email_change_object, EmailChangeStatus) assert isinstance(email_change_object, EmailChangeStatus)
@ -244,7 +244,7 @@ def json_change_settings(
return_data=return_data, return_data=return_data,
): ):
raise JsonableError(_("Wrong password!")) raise JsonableError(_("Wrong password!"))
except RateLimited as e: except RateLimitedError as e:
assert e.secs_to_freedom is not None assert e.secs_to_freedom is not None
secs_to_freedom = int(e.secs_to_freedom) secs_to_freedom = int(e.secs_to_freedom)
raise JsonableError( raise JsonableError(
@ -300,7 +300,7 @@ def json_change_settings(
user_profile, domain="email_change_by_user" user_profile, domain="email_change_by_user"
).rate_limit() ).rate_limit()
if ratelimited: if ratelimited:
raise RateLimited(time_until_free) raise RateLimitedError(time_until_free)
do_start_email_change_process(user_profile, new_email) do_start_email_change_process(user_profile, new_email)

View File

@ -41,8 +41,8 @@ from zerver.lib.exceptions import (
CannotDeactivateLastUserError, CannotDeactivateLastUserError,
JsonableError, JsonableError,
MissingAuthenticationError, MissingAuthenticationError,
OrganizationAdministratorRequired, OrganizationAdministratorRequiredError,
OrganizationOwnerRequired, OrganizationOwnerRequiredError,
) )
from zerver.lib.integrations import EMBEDDED_BOTS from zerver.lib.integrations import EMBEDDED_BOTS
from zerver.lib.rate_limiter import rate_limit_spectator_attachment_access_by_file from zerver.lib.rate_limiter import rate_limit_spectator_attachment_access_by_file
@ -87,7 +87,7 @@ from zerver.models import (
DisposableEmailError, DisposableEmailError,
DomainNotAllowedForRealmError, DomainNotAllowedForRealmError,
EmailContainsPlusError, EmailContainsPlusError,
InvalidFakeEmailDomain, InvalidFakeEmailDomainError,
Message, Message,
Realm, Realm,
Service, Service,
@ -117,7 +117,7 @@ def deactivate_user_backend(
) -> HttpResponse: ) -> HttpResponse:
target = access_user_by_id(user_profile, user_id, for_admin=True) target = access_user_by_id(user_profile, user_id, for_admin=True)
if target.is_realm_owner and not user_profile.is_realm_owner: if target.is_realm_owner and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
if check_last_owner(target): if check_last_owner(target):
raise JsonableError(_("Cannot deactivate the only organization owner")) raise JsonableError(_("Cannot deactivate the only organization owner"))
if deactivation_notification_comment is not None: if deactivation_notification_comment is not None:
@ -231,9 +231,9 @@ def update_user_backend(
# #
# Logic replicated in patch_bot_backend. # Logic replicated in patch_bot_backend.
if UserProfile.ROLE_REALM_OWNER in [role, target.role] and not user_profile.is_realm_owner: if UserProfile.ROLE_REALM_OWNER in [role, target.role] and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
elif not user_profile.is_realm_admin: elif not user_profile.is_realm_admin:
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
if target.role == UserProfile.ROLE_REALM_OWNER and check_last_owner(target): if target.role == UserProfile.ROLE_REALM_OWNER and check_last_owner(target):
raise JsonableError( raise JsonableError(
@ -367,9 +367,9 @@ def patch_bot_backend(
if role is not None and bot.role != role: if role is not None and bot.role != role:
# Logic duplicated from update_user_backend. # Logic duplicated from update_user_backend.
if UserProfile.ROLE_REALM_OWNER in [role, bot.role] and not user_profile.is_realm_owner: if UserProfile.ROLE_REALM_OWNER in [role, bot.role] and not user_profile.is_realm_owner:
raise OrganizationOwnerRequired() raise OrganizationOwnerRequiredError()
elif not user_profile.is_realm_admin: elif not user_profile.is_realm_admin:
raise OrganizationAdministratorRequired() raise OrganizationAdministratorRequiredError()
do_change_user_role(bot, role, acting_user=user_profile) do_change_user_role(bot, role, acting_user=user_profile)
@ -484,7 +484,7 @@ def add_bot_backend(
full_name = check_full_name(full_name_raw) full_name = check_full_name(full_name_raw)
try: try:
email = Address(username=short_name, domain=user_profile.realm.get_bot_domain()).addr_spec email = Address(username=short_name, domain=user_profile.realm.get_bot_domain()).addr_spec
except InvalidFakeEmailDomain: except InvalidFakeEmailDomainError:
raise JsonableError( raise JsonableError(
_( _(
"Can't create bots until FAKE_EMAIL_DOMAIN is correctly configured.\n" "Can't create bots until FAKE_EMAIL_DOMAIN is correctly configured.\n"

View File

@ -3,7 +3,7 @@ from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value
@ -148,7 +148,7 @@ def get_event_name(payload: WildValue, branches: Optional[str]) -> Optional[str]
return None return None
if event_name in EVENT_FUNCTION_MAPPER: if event_name in EVENT_FUNCTION_MAPPER:
return event_name return event_name
raise UnsupportedWebhookEventType(event_name) raise UnsupportedWebhookEventTypeError(event_name)
EVENT_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], str]] = { EVENT_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], str]] = {

View File

@ -4,7 +4,7 @@ import string
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_string, to_wild_value from zerver.lib.validator import WildValue, check_string, to_wild_value
@ -47,7 +47,7 @@ def api_basecamp_webhook(
event = get_event_type(payload) event = get_event_type(payload)
if event not in SUPPORT_EVENTS: if event not in SUPPORT_EVENTS:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
subject = get_project_name(payload) subject = get_project_name(payload)
if event.startswith("document_"): if event.startswith("document_"):
@ -72,7 +72,7 @@ def api_basecamp_webhook(
body = get_comment_body(event, payload) body = get_comment_body(event, payload)
event = "comment" event = "comment"
else: else:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
check_send_webhook_message(request, user_profile, subject, body, event) check_send_webhook_message(request, user_profile, subject, body, event)
return json_success(request) return json_success(request)

View File

@ -7,7 +7,7 @@ from typing import Dict, List, Optional, Protocol
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import log_unsupported_webhook_event, webhook_view from zerver.decorator import log_unsupported_webhook_event, webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value
@ -196,7 +196,7 @@ def get_type(request: HttpRequest, payload: WildValue) -> str:
if event_key == "repo:updated": if event_key == "repo:updated":
return event_key return event_key
raise UnsupportedWebhookEventType(event_key) raise UnsupportedWebhookEventTypeError(event_key)
class BodyGetter(Protocol): class BodyGetter(Protocol):

View File

@ -5,7 +5,7 @@ from typing import Dict, List, Optional, Protocol
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value
@ -169,7 +169,7 @@ def repo_push_branch_data(payload: WildValue, change: WildValue) -> Dict[str, st
body = get_remove_branch_event_message(user_name, branch_name) body = get_remove_branch_event_message(user_name, branch_name)
else: else:
message = "{}.{}".format(payload["eventKey"].tame(check_string), event_type) # nocoverage message = "{}.{}".format(payload["eventKey"].tame(check_string), event_type) # nocoverage
raise UnsupportedWebhookEventType(message) raise UnsupportedWebhookEventTypeError(message)
subject = TOPIC_WITH_BRANCH_TEMPLATE.format(repo=repo_name, branch=branch_name) subject = TOPIC_WITH_BRANCH_TEMPLATE.format(repo=repo_name, branch=branch_name)
return {"subject": subject, "body": body} return {"subject": subject, "body": body}
@ -186,7 +186,7 @@ def repo_push_tag_data(payload: WildValue, change: WildValue) -> Dict[str, str]:
action = "removed" action = "removed"
else: else:
message = "{}.{}".format(payload["eventKey"].tame(check_string), event_type) # nocoverage message = "{}.{}".format(payload["eventKey"].tame(check_string), event_type) # nocoverage
raise UnsupportedWebhookEventType(message) raise UnsupportedWebhookEventTypeError(message)
subject = BITBUCKET_TOPIC_TEMPLATE.format(repository_name=repo_name) subject = BITBUCKET_TOPIC_TEMPLATE.format(repository_name=repo_name)
body = get_push_tag_event_message(get_user_name(payload), tag_name, action=action) body = get_push_tag_event_message(get_user_name(payload), tag_name, action=action)
@ -213,7 +213,7 @@ def repo_push_handler(
message = "{}.{}".format( message = "{}.{}".format(
payload["eventKey"].tame(check_string), event_target_type payload["eventKey"].tame(check_string), event_target_type
) # nocoverage ) # nocoverage
raise UnsupportedWebhookEventType(message) raise UnsupportedWebhookEventTypeError(message)
return data return data
@ -446,7 +446,7 @@ def api_bitbucket3_webhook(
assert eventkey is not None assert eventkey is not None
handler = EVENT_HANDLER_MAP.get(eventkey) handler = EVENT_HANDLER_MAP.get(eventkey)
if handler is None: if handler is None:
raise UnsupportedWebhookEventType(eventkey) raise UnsupportedWebhookEventTypeError(eventkey)
data = handler(payload, branches=branches, include_title=user_specified_topic) data = handler(payload, branches=branches, include_title=user_specified_topic)
for element in data: for element in data:

View File

@ -4,7 +4,7 @@ from typing import Callable, Dict, Iterable, Iterator, List, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import ( from zerver.lib.validator import (
@ -695,7 +695,7 @@ def send_stream_messages_for_actions(
body_func = EVENT_BODY_FUNCTION_MAPPER.get(event) body_func = EVENT_BODY_FUNCTION_MAPPER.get(event)
topic_func = get_topic_function_based_on_type(payload, action) topic_func = get_topic_function_based_on_type(payload, action)
if body_func is None or topic_func is None: if body_func is None or topic_func is None:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
topic = topic_func(payload, action) topic = topic_func(payload, action)
body = body_func(payload, action) body = body_func(payload, action)

View File

@ -1,7 +1,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value
@ -32,7 +32,7 @@ def api_freshping_webhook(
subject = get_subject_for_http_request(payload) subject = get_subject_for_http_request(payload)
check_state_name = payload["webhook_event_data"]["check_state_name"].tame(check_string) check_state_name = payload["webhook_event_data"]["check_state_name"].tame(check_string)
if check_state_name not in CHECK_STATE_NAME_TO_EVENT_TYPE: if check_state_name not in CHECK_STATE_NAME_TO_EVENT_TYPE:
raise UnsupportedWebhookEventType(check_state_name) raise UnsupportedWebhookEventTypeError(check_state_name)
check_send_webhook_message( check_send_webhook_message(
request, request,

View File

@ -17,7 +17,7 @@ def build_instance_url(instance_id: int) -> str:
return f"https://codein.withgoogle.com/dashboard/task-instances/{instance_id}/" return f"https://codein.withgoogle.com/dashboard/task-instances/{instance_id}/"
class UnknownEventType(Exception): class UnknownEventTypeError(Exception):
pass pass
@ -155,7 +155,7 @@ def get_event(payload: WildValue) -> Optional[str]:
if event in EVENTS_FUNCTION_MAPPER: if event in EVENTS_FUNCTION_MAPPER:
return event return event
raise UnknownEventType(f"Event '{event}' is unknown and cannot be handled") # nocoverage raise UnknownEventTypeError(f"Event '{event}' is unknown and cannot be handled") # nocoverage
def get_body_based_on_event(event: str) -> Callable[[WildValue], str]: def get_body_based_on_event(event: str) -> Callable[[WildValue], str]:

View File

@ -5,7 +5,7 @@ from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import log_unsupported_webhook_event, webhook_view from zerver.decorator import log_unsupported_webhook_event, webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import ( from zerver.lib.validator import (
@ -759,7 +759,7 @@ def api_github_webhook(
""" """
header_event = validate_extract_webhook_http_header(request, "X-GitHub-Event", "GitHub") header_event = validate_extract_webhook_http_header(request, "X-GitHub-Event", "GitHub")
if header_event is None: if header_event is None:
raise UnsupportedWebhookEventType("no header provided") raise UnsupportedWebhookEventTypeError("no header provided")
event = get_zulip_event_name(header_event, payload, branches) event = get_zulip_event_name(header_event, payload, branches)
if event is None: if event is None:
@ -832,7 +832,7 @@ def get_zulip_event_name(
else: else:
# this means GH has actually added new actions since September 2020, # this means GH has actually added new actions since September 2020,
# so it's a bit more cause for alarm # so it's a bit more cause for alarm
raise UnsupportedWebhookEventType(f"unsupported team action {action}") raise UnsupportedWebhookEventTypeError(f"unsupported team action {action}")
elif header_event in list(EVENT_FUNCTION_MAPPER.keys()): elif header_event in list(EVENT_FUNCTION_MAPPER.keys()):
return header_event return header_event
elif header_event in IGNORED_EVENTS: elif header_event in IGNORED_EVENTS:
@ -841,4 +841,4 @@ def get_zulip_event_name(
complete_event = "{}:{}".format( complete_event = "{}:{}".format(
header_event, payload.get("action", "???").tame(check_string) header_event, payload.get("action", "???").tame(check_string)
) # nocoverage ) # nocoverage
raise UnsupportedWebhookEventType(complete_event) raise UnsupportedWebhookEventTypeError(complete_event)

View File

@ -5,7 +5,7 @@ from typing import Dict, List, Optional, Protocol, Union
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value
@ -517,4 +517,4 @@ def get_event(request: HttpRequest, payload: WildValue, branches: Optional[str])
if event in list(EVENT_FUNCTION_MAPPER.keys()): if event in list(EVENT_FUNCTION_MAPPER.keys()):
return event return event
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)

View File

@ -4,7 +4,7 @@ from typing import Dict, List, Optional, Protocol
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value
@ -247,7 +247,7 @@ def gogs_webhook_main(
) )
else: else:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
check_send_webhook_message(request, user_profile, topic, body, event) check_send_webhook_message(request, user_profile, topic, body, event)
return json_success(request) return json_success(request)

View File

@ -1,7 +1,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value
@ -58,6 +58,6 @@ def api_gosquared_webhook(
) )
check_send_webhook_message(request, user_profile, topic, body, "chat_message") check_send_webhook_message(request, user_profile, topic, body, "chat_message")
else: else:
raise UnsupportedWebhookEventType("unknown_event") raise UnsupportedWebhookEventTypeError("unknown_event")
return json_success(request) return json_success(request)

View File

@ -5,7 +5,7 @@ from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import ( from zerver.lib.validator import (
@ -121,7 +121,7 @@ def api_groove_webhook(
assert event is not None assert event is not None
handler = EVENTS_FUNCTION_MAPPER.get(event) handler = EVENTS_FUNCTION_MAPPER.get(event)
if handler is None: if handler is None:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
body = handler(payload) body = handler(payload)
topic = "notifications" topic = "notifications"

View File

@ -5,7 +5,7 @@ from django.db.models import Q
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_string, to_wild_value
@ -59,7 +59,7 @@ def handle_scanning_completed_event(
scan_results = "" scan_results = ""
scan_overview = payload["event_data"]["resources"][0]["scan_overview"] scan_overview = payload["event_data"]["resources"][0]["scan_overview"]
if "application/vnd.security.vulnerability.report; version=1.1" not in scan_overview: if "application/vnd.security.vulnerability.report; version=1.1" not in scan_overview:
raise UnsupportedWebhookEventType("Unsupported harbor scanning webhook payload") raise UnsupportedWebhookEventTypeError("Unsupported harbor scanning webhook payload")
scan_summaries = scan_overview["application/vnd.security.vulnerability.report; version=1.1"][ scan_summaries = scan_overview["application/vnd.security.vulnerability.report; version=1.1"][
"summary" "summary"
]["summary"] ]["summary"]
@ -109,7 +109,7 @@ def api_harbor_webhook(
content_func = EVENT_FUNCTION_MAPPER.get(event) content_func = EVENT_FUNCTION_MAPPER.get(event)
if content_func is None: if content_func is None:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
content: str = content_func(payload, user_profile, operator_username) content: str = content_func(payload, user_profile, operator_username)

View File

@ -5,7 +5,7 @@ from typing import Callable, Dict, List, Tuple
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value
@ -337,7 +337,7 @@ def api_intercom_webhook(
handler = EVENT_TO_FUNCTION_MAPPER.get(event_type) handler = EVENT_TO_FUNCTION_MAPPER.get(event_type)
if handler is None: if handler is None:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
topic, body = handler(payload) topic, body = handler(payload)
check_send_webhook_message(request, user_profile, topic, body, event_type) check_send_webhook_message(request, user_profile, topic, body, event_type)

View File

@ -8,7 +8,7 @@ from django.db.models import Q
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import AnomalousWebhookPayload, UnsupportedWebhookEventType from zerver.lib.exceptions import AnomalousWebhookPayloadError, UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_none_or, check_string, to_wild_value from zerver.lib.validator import WildValue, check_none_or, check_string, to_wild_value
@ -363,13 +363,13 @@ def api_jira_webhook(
return json_success(request) return json_success(request)
if event is None: if event is None:
raise AnomalousWebhookPayload() raise AnomalousWebhookPayloadError()
if event is not None: if event is not None:
content_func = JIRA_CONTENT_FUNCTION_MAPPER.get(event) content_func = JIRA_CONTENT_FUNCTION_MAPPER.get(event)
if content_func is None: if content_func is None:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
subject = get_issue_subject(payload) subject = get_issue_subject(payload)
content: str = content_func(payload, user_profile) content: str = content_func(payload, user_profile)

View File

@ -3,7 +3,7 @@ from typing import Dict, List
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_string, to_wild_value
@ -141,4 +141,4 @@ def get_body_for_http_request(payload: WildValue) -> str:
else: else:
return get_body_for_tracks_imported_event(payload) return get_body_for_tracks_imported_event(payload)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)

View File

@ -3,7 +3,7 @@ from typing import Tuple
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_string, to_wild_value from zerver.lib.validator import WildValue, check_string, to_wild_value
@ -63,6 +63,6 @@ def get_template(request: HttpRequest, payload: WildValue) -> Tuple[str, str]:
elif event in ALL_EVENT_TYPES: elif event in ALL_EVENT_TYPES:
message_template += "is now {state}.".format(state=payload["state"].tame(check_string)) message_template += "is now {state}.".format(state=payload["state"].tame(check_string))
else: else:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
return message_template, event return message_template, event

View File

@ -4,7 +4,7 @@ from typing import Dict, Union
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value
@ -250,7 +250,7 @@ def api_pagerduty_webhook(
break break
if message_type not in PAGER_DUTY_EVENT_NAMES: if message_type not in PAGER_DUTY_EVENT_NAMES:
raise UnsupportedWebhookEventType(message_type) raise UnsupportedWebhookEventTypeError(message_type)
format_dict = build_pagerduty_formatdict(message) format_dict = build_pagerduty_formatdict(message)
send_formated_pagerduty(request, user_profile, message_type, format_dict) send_formated_pagerduty(request, user_profile, message_type, format_dict)
@ -264,7 +264,7 @@ def api_pagerduty_webhook(
break break
if message_event not in PAGER_DUTY_EVENT_NAMES_V2: if message_event not in PAGER_DUTY_EVENT_NAMES_V2:
raise UnsupportedWebhookEventType(message_event) raise UnsupportedWebhookEventTypeError(message_event)
format_dict = build_pagerduty_formatdict_v2(message) format_dict = build_pagerduty_formatdict_v2(message)
send_formated_pagerduty(request, user_profile, message_event, format_dict) send_formated_pagerduty(request, user_profile, message_event, format_dict)
@ -275,7 +275,7 @@ def api_pagerduty_webhook(
event_type = event.get("event_type").tame(check_none_or(check_string)) event_type = event.get("event_type").tame(check_none_or(check_string))
if event_type not in PAGER_DUTY_EVENT_NAMES_V3: if event_type not in PAGER_DUTY_EVENT_NAMES_V3:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
format_dict = build_pagerduty_formatdict_v3(event) format_dict = build_pagerduty_formatdict_v3(event)
send_formated_pagerduty(request, user_profile, event_type, format_dict) send_formated_pagerduty(request, user_profile, event_type, format_dict)

View File

@ -2,7 +2,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_string, to_wild_value from zerver.lib.validator import WildValue, check_string, to_wild_value
@ -51,7 +51,7 @@ def api_pingdom_webhook(
subject = get_subject_for_http_request(payload) subject = get_subject_for_http_request(payload)
body = get_body_for_http_request(payload) body = get_body_for_http_request(payload)
else: else:
raise UnsupportedWebhookEventType(check_type) raise UnsupportedWebhookEventTypeError(check_type)
check_send_webhook_message(request, user_profile, subject, body, check_type) check_send_webhook_message(request, user_profile, subject, body, check_type)
return json_success(request) return json_success(request)

View File

@ -2,7 +2,7 @@ from unittest import mock
import orjson import orjson
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.test_classes import WebhookTestCase from zerver.lib.test_classes import WebhookTestCase
from zerver.webhooks.pivotal.view import api_pivotal_webhook_v5 from zerver.webhooks.pivotal.view import api_pivotal_webhook_v5
@ -218,7 +218,7 @@ Try again next time
self.assertEqual(result[0], "#0: ") self.assertEqual(result[0], "#0: ")
bad = orjson.loads(self.get_body("bad_kind")) bad = orjson.loads(self.get_body("bad_kind"))
with self.assertRaisesRegex(UnsupportedWebhookEventType, "'unknown_kind'.* supported"): with self.assertRaisesRegex(UnsupportedWebhookEventTypeError, "'unknown_kind'.* supported"):
with mock.patch("zerver.webhooks.pivotal.view.orjson.loads", return_value=bad): with mock.patch("zerver.webhooks.pivotal.view.orjson.loads", return_value=bad):
api_pivotal_webhook_v5(request, hamlet) api_pivotal_webhook_v5(request, hamlet)

View File

@ -8,7 +8,7 @@ from django.http import HttpRequest, HttpResponse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import JsonableError, UnsupportedWebhookEventType from zerver.lib.exceptions import JsonableError, UnsupportedWebhookEventTypeError
from zerver.lib.request import has_request_variables from zerver.lib.request import has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.webhooks.common import check_send_webhook_message from zerver.lib.webhooks.common import check_send_webhook_message
@ -170,7 +170,7 @@ def api_pivotal_webhook_v5(request: HttpRequest, user_profile: UserProfile) -> T
# Known but unsupported Pivotal event types # Known but unsupported Pivotal event types
pass pass
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
return subject, content, f"{event_type}_v5" return subject, content, f"{event_type}_v5"

View File

@ -1,7 +1,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_string, to_wild_value from zerver.lib.validator import WildValue, check_string, to_wild_value
@ -103,4 +103,4 @@ def get_body_for_http_request(payload: WildValue) -> str:
elif event_type == "Grab": elif event_type == "Grab":
return get_body_for_movie_grabbed_event(payload) return get_body_for_movie_grabbed_event(payload)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)

View File

@ -3,7 +3,7 @@ import time
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import ( from zerver.lib.validator import (
@ -43,7 +43,7 @@ def api_raygun_webhook(
elif event == "error_activity": elif event == "error_activity":
message = compose_activity_message(payload) message = compose_activity_message(payload)
else: else:
raise UnsupportedWebhookEventType(event) raise UnsupportedWebhookEventTypeError(event)
topic = "test" topic = "test"
@ -232,7 +232,7 @@ def compose_notification_message(payload: WildValue) -> str:
elif "FollowUp" in event_type: elif "FollowUp" in event_type:
return notification_message_follow_up(payload) return notification_message_follow_up(payload)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
def activity_message(payload: WildValue) -> str: def activity_message(payload: WildValue) -> str:
@ -292,7 +292,7 @@ def compose_activity_message(payload: WildValue) -> str:
): ):
return activity_message(payload) return activity_message(payload)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
def parse_time(timestamp: str) -> str: def parse_time(timestamp: str) -> str:

View File

@ -1,7 +1,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value from zerver.lib.validator import WildValue, check_int, check_none_or, check_string, to_wild_value
@ -194,6 +194,6 @@ def api_reviewboard_webhook(
topic = get_review_request_repo_title(payload) topic = get_review_request_repo_title(payload)
check_send_webhook_message(request, user_profile, topic, body, event_type) check_send_webhook_message(request, user_profile, topic, body, event_type)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)
return json_success(request) return json_success(request)

View File

@ -4,7 +4,7 @@ from django.core.exceptions import ValidationError
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_string, to_wild_value from zerver.lib.validator import WildValue, check_string, to_wild_value
@ -55,7 +55,7 @@ def get_event_name(payload: WildValue, branches: Optional[str]) -> Optional[str]
return None return None
if event_name in EVENT_FUNCTION_MAPPER: if event_name in EVENT_FUNCTION_MAPPER:
return event_name return event_name
raise UnsupportedWebhookEventType(event_name) raise UnsupportedWebhookEventTypeError(event_name)
def get_repository_name(payload: WildValue) -> str: def get_repository_name(payload: WildValue) -> str:

View File

@ -6,7 +6,7 @@ from urllib.parse import urljoin
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.webhooks.common import check_send_webhook_message from zerver.lib.webhooks.common import check_send_webhook_message
@ -95,7 +95,7 @@ def handle_event_payload(event: Dict[str, Any]) -> Tuple[str, str]:
"""Handle either an exception type event or a message type event payload.""" """Handle either an exception type event or a message type event payload."""
# We shouldn't support the officially deprecated Raven series of SDKs. # We shouldn't support the officially deprecated Raven series of SDKs.
if int(event["version"]) < 7: if int(event["version"]) < 7:
raise UnsupportedWebhookEventType("Raven SDK") raise UnsupportedWebhookEventTypeError("Raven SDK")
subject = event["title"] subject = event["title"]
platform_name = event["platform"] platform_name = event["platform"]
@ -159,7 +159,7 @@ def handle_event_payload(event: Dict[str, Any]) -> Tuple[str, str]:
body = MESSAGE_EVENT_TEMPLATE.format(**context) body = MESSAGE_EVENT_TEMPLATE.format(**context)
else: else:
raise UnsupportedWebhookEventType("unknown-event type") raise UnsupportedWebhookEventTypeError("unknown-event type")
return (subject, body) return (subject, body)
@ -211,7 +211,7 @@ def handle_issue_payload(
body = ISSUE_IGNORED_MESSAGE_TEMPLATE.format(**context) body = ISSUE_IGNORED_MESSAGE_TEMPLATE.format(**context)
else: else:
raise UnsupportedWebhookEventType("unknown-issue-action type") raise UnsupportedWebhookEventTypeError("unknown-issue-action type")
return (subject, body) return (subject, body)
@ -266,7 +266,7 @@ def api_sentry_webhook(
elif "issue" in data: elif "issue" in data:
subject, body = handle_issue_payload(payload["action"], data["issue"], payload["actor"]) subject, body = handle_issue_payload(payload["action"], data["issue"], payload["actor"])
else: else:
raise UnsupportedWebhookEventType(str(list(data.keys()))) raise UnsupportedWebhookEventTypeError(str(list(data.keys())))
else: else:
subject, body = handle_deprecated_payload(payload) subject, body = handle_deprecated_payload(payload)

View File

@ -1,7 +1,7 @@
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from zerver.decorator import webhook_view from zerver.decorator import webhook_view
from zerver.lib.exceptions import UnsupportedWebhookEventType from zerver.lib.exceptions import UnsupportedWebhookEventTypeError
from zerver.lib.request import REQ, has_request_variables from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value from zerver.lib.validator import WildValue, check_bool, check_int, check_string, to_wild_value
@ -167,4 +167,4 @@ def get_body_for_http_request(payload: WildValue) -> str:
else: else:
return get_body_for_episode_deleted_event(payload) return get_body_for_episode_deleted_event(payload)
else: else:
raise UnsupportedWebhookEventType(event_type) raise UnsupportedWebhookEventTypeError(event_type)

Some files were not shown because too many files have changed in this diff Show More