Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/framework/exceptions.py b/framework/exceptions.py
new file mode 100644
index 0000000..51c9951
--- /dev/null
+++ b/framework/exceptions.py
@@ -0,0 +1,184 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Exception classes used throughout monorail.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+
+class ErrorAggregator():
+ """Class for holding errors and raising an exception for many."""
+
+ def __init__(self, exc_type):
+ # type: (type) -> None
+ self.exc_type = exc_type
+ self.error_messages = []
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ # If no exceptions were raised within the context, we check
+ # if any error messages were accumulated that we should raise
+ # an exception for.
+ if exc_type == None:
+ self.RaiseIfErrors()
+ # If there were exceptions raised within the context, we do
+ # nothing to suppress them.
+
+ def AddErrorMessage(self, message, *args, **kwargs):
+ # type: (str, *Any, **Any) -> None
+ """Add a new error message.
+
+ Args:
+ message: An error message, to be formatted using *args and **kwargs.
+ *args: passed in to str.format.
+ **kwargs: passed in to str.format.
+ """
+ self.error_messages.append(message.format(*args, **kwargs))
+
+ def RaiseIfErrors(self):
+ # type: () -> None
+ """If there are errors, raise one exception."""
+ if self.error_messages:
+ raise self.exc_type("\n".join(self.error_messages))
+
+
+class Error(Exception):
+ """Base class for errors from this module."""
+ pass
+
+
+class ActionNotSupported(Error):
+ """The user is trying to do something we do not support."""
+ pass
+
+
+class InputException(Error):
+ """Error in user input processing."""
+ pass
+
+
+class ProjectAlreadyExists(Error):
+ """Tried to create a project that already exists."""
+
+
+class FieldDefAlreadyExists(Error):
+ """Tried to create a custom field that already exists."""
+
+
+class ComponentDefAlreadyExists(Error):
+ """Tried to create a component that already exists."""
+
+
+class NoSuchProjectException(Error):
+ """No project with the specified name exists."""
+ pass
+
+
+class NoSuchTemplateException(Error):
+ """No template with the specified name exists."""
+ pass
+
+
+class NoSuchUserException(Error):
+ """No user with the specified name exists."""
+ pass
+
+
+class NoSuchIssueException(Error):
+ """The requested issue was not found."""
+ pass
+
+
+class NoSuchAttachmentException(Error):
+ """The requested attachment was not found."""
+ pass
+
+
+class NoSuchCommentException(Error):
+ """The requested comment was not found."""
+ pass
+
+
+class NoSuchAmendmentException(Error):
+ """The requested amendment was not found."""
+ pass
+
+
+class NoSuchComponentException(Error):
+ """No component with the specified name exists."""
+ pass
+
+
+class InvalidComponentNameException(Error):
+ """The component name is invalid."""
+ pass
+
+
+class InvalidHotlistException(Error):
+ """The specified hotlist is invalid."""
+ pass
+
+
+class NoSuchFieldDefException(Error):
+ """No field def for specified project exists."""
+ pass
+
+
+class InvalidFieldTypeException(Error):
+ """Expected field type and actual field type do not match."""
+ pass
+
+
+class NoSuchIssueApprovalException(Error):
+ """The requested approval for the issue was not found."""
+ pass
+
+
+class CircularGroupException(Error):
+ """Circular nested group exception."""
+ pass
+
+
+class GroupExistsException(Error):
+ """Group already exists exception."""
+ pass
+
+
+class NoSuchGroupException(Error):
+ """Requested group was not found exception."""
+ pass
+
+
+class InvalidExternalIssueReference(Error):
+ """Improperly formatted external issue reference.
+
+ External issue references must be of the form:
+
+ $tracker_shortname/$tracker_specific_id
+
+ For example, issuetracker.google.com issues:
+
+ b/123456789
+ """
+ pass
+
+
+class PageTokenException(Error):
+ """Incorrect page tokens."""
+ pass
+
+
+class FilterRuleException(Error):
+ """Violates a filter rule that should show error."""
+ pass
+
+
+class OverAttachmentQuota(Error):
+ """Project will exceed quota if the current operation is allowed."""
+ pass