aboutsummaryrefslogtreecommitdiff
path: root/wa/framework/exception.py
blob: ee17a50ed828322833b4797903375e3b41ebb371 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#    Copyright 2013-2018 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# pylint: disable=unused-import
from devlib.exception import (DevlibError, HostError, TimeoutError,  # pylint: disable=redefined-builtin
                              TargetError, TargetNotRespondingError)

from wa.utils.misc import get_traceback


class WAError(Exception):
    """Base class for all Workload Automation exceptions."""
    @property
    def message(self):
        if self.args:
            return self.args[0]
        return ''


class NotFoundError(WAError):
    """Raised when the specified item is not found."""
    pass


class ValidationError(WAError):
    """Raised on failure to validate an extension."""
    pass


class ExecutionError(WAError):
    """Error encountered by the execution framework."""
    pass


class WorkloadError(WAError):
    """General Workload error."""
    pass


class JobError(WAError):
    """Job execution error."""
    pass


class InstrumentError(WAError):
    """General Instrument error."""
    pass


class OutputProcessorError(WAError):
    """General OutputProcessor error."""
    pass


class ResourceError(WAError):
    """General Resolver error."""
    pass


class CommandError(WAError):
    """Raised by commands when they have encountered an error condition
    during execution."""
    pass


class ToolError(WAError):
    """Raised by tools when they have encountered an error condition
    during execution."""
    pass


class ConfigError(WAError):
    """Raised when configuration provided is invalid. This error suggests that
    the user should modify their config and try again."""
    pass


class SerializerSyntaxError(Exception):
    """
    Error loading a serialized structure from/to a file handle.
    """
    @property
    def message(self):
        if self.args:
            return self.args[0]
        return ''

    def __init__(self, message, line=None, column=None):
        super(SerializerSyntaxError, self).__init__(message)
        self.line = line
        self.column = column

    def __str__(self):
        linestring = ' on line {}'.format(self.line) if self.line else ''
        colstring = ' in column {}'.format(self.column) if self.column else ''
        message = 'Syntax Error{}: {}'
        return message.format(''.join([linestring, colstring]), self.message)


class PluginLoaderError(WAError):
    """Raised when there is an error loading an extension or
    an external resource. Apart form the usual message, the __init__
    takes an exc_info parameter which should be the result of
    sys.exc_info() for the original exception (if any) that
    caused the error."""

    def __init__(self, message, exc_info=None):
        super(PluginLoaderError, self).__init__(message)
        self.exc_info = exc_info

    def __str__(self):
        if self.exc_info:
            orig = self.exc_info[1]
            orig_name = type(orig).__name__
            if isinstance(orig, WAError):
                reason = 'because of:\n{}: {}'.format(orig_name, orig)
            else:
                text = 'because of:\n{}\n{}: {}'
                reason = text.format(get_traceback(self.exc_info), orig_name, orig)
            return '\n'.join([self.message, reason])
        else:
            return self.message


class WorkerThreadError(WAError):
    """
    This should get raised  in the main thread if a non-WAError-derived
    exception occurs on a worker/background thread. If a WAError-derived
    exception is raised in the worker, then it that exception should be
    re-raised on the main thread directly -- the main point of this is to
    preserve the backtrace in the output, and backtrace doesn't get output for
    WAErrors.

    """

    def __init__(self, thread, exc_info):
        self.thread = thread
        self.exc_info = exc_info
        orig = self.exc_info[1]
        orig_name = type(orig).__name__
        text = 'Exception of type {} occured on thread {}:\n{}\n{}: {}'
        message = text.format(orig_name, thread, get_traceback(self.exc_info),
                              orig_name, orig)
        super(WorkerThreadError, self).__init__(message)