Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/framework/errors_impl.py: 68%
205 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Exception types for TensorFlow errors."""
17import traceback
18import warnings
20from tensorflow.core.lib.core import error_codes_pb2
21from tensorflow.python import _pywrap_py_exception_registry
22from tensorflow.python.client import pywrap_tf_session as c_api
23from tensorflow.python.framework import c_api_util
24from tensorflow.python.util import compat
25from tensorflow.python.util import deprecation
26from tensorflow.python.util import tf_inspect
27from tensorflow.python.util.tf_export import tf_export
30class InaccessibleTensorError(ValueError):
31 pass
34@tf_export("errors.OperatorNotAllowedInGraphError", v1=[])
35class OperatorNotAllowedInGraphError(TypeError):
36 """Raised when an unsupported operator is present in Graph execution.
38 For example, using a `tf.Tensor` as a Python `bool` inside a Graph will
39 raise `OperatorNotAllowedInGraphError`. Iterating over values inside a
40 `tf.Tensor` is also not supported in Graph execution.
42 Example:
43 >>> @tf.function
44 ... def iterate_over(t):
45 ... a,b,c = t
46 ... return a
47 >>>
48 >>> iterate_over(tf.constant([1, 2, 3]))
49 Traceback (most recent call last):
50 ...
51 OperatorNotAllowedInGraphError: ...
53 """
54 pass
57@tf_export("errors.OpError", v1=["errors.OpError", "OpError"])
58@deprecation.deprecated_endpoints("OpError")
59class OpError(Exception):
60 """The base class for TensorFlow exceptions.
62 Usually, TensorFlow will raise a more specific subclass of `OpError` from the
63 `tf.errors` module.
64 """
66 def __init__(self, node_def, op, message, error_code, *args):
67 """Creates a new `OpError` indicating that a particular op failed.
69 Args:
70 node_def: The `node_def_pb2.NodeDef` proto representing the op that
71 failed, if known; otherwise None.
72 op: The `ops.Operation` that failed, if known; otherwise None. During
73 eager execution, this field is always `None`.
74 message: The message string describing the failure.
75 error_code: The `error_codes_pb2.Code` describing the error.
76 *args: If not empty, it should contain a dictionary describing details
77 about the error. This argument is inspired by Abseil payloads:
78 https://github.com/abseil/abseil-cpp/blob/master/absl/status/status.h
79 """
80 super(OpError, self).__init__()
81 self._node_def = node_def
82 self._op = op
83 self._message = message
84 self._error_code = error_code
85 if args:
86 self._experimental_payloads = args[0]
87 else:
88 self._experimental_payloads = {}
90 def __reduce__(self):
91 # Allow the subclasses to accept less arguments in their __init__.
92 init_argspec = tf_inspect.getargspec(self.__class__.__init__)
93 args = tuple(getattr(self, arg) for arg in init_argspec.args[1:])
94 return self.__class__, args
96 @property
97 def message(self):
98 """The error message that describes the error."""
99 return self._message
101 @property
102 def op(self):
103 """The operation that failed, if known.
105 *N.B.* If the failed op was synthesized at runtime, e.g. a `Send`
106 or `Recv` op, there will be no corresponding
107 `tf.Operation`
108 object. In that case, this will return `None`, and you should
109 instead use the `tf.errors.OpError.node_def` to
110 discover information about the op.
112 Returns:
113 The `Operation` that failed, or None.
114 """
115 return self._op
117 @property
118 def error_code(self):
119 """The integer error code that describes the error."""
120 return self._error_code
122 @property
123 def node_def(self):
124 """The `NodeDef` proto representing the op that failed."""
125 return self._node_def
127 @property
128 def experimental_payloads(self):
129 """A dictionary describing the details of the error."""
130 return self._experimental_payloads
132 def __str__(self):
133 if self._op is not None:
134 output = [
135 "%s\n\nOriginal stack trace for %r:\n" % (
136 self.message,
137 self._op.name,
138 )
139 ]
140 curr_traceback_list = traceback.format_list(self._op.traceback or [])
141 output.extend(curr_traceback_list)
142 # pylint: disable=protected-access
143 original_op = self._op._original_op
144 # pylint: enable=protected-access
145 while original_op is not None:
146 output.append(
147 "\n...which was originally created as op %r, defined at:\n" %
148 (original_op.name,))
149 prev_traceback_list = curr_traceback_list
150 curr_traceback_list = traceback.format_list(original_op.traceback or [])
152 # Attempt to elide large common subsequences of the subsequent
153 # stack traces.
154 #
155 # TODO(mrry): Consider computing the actual longest common subsequence.
156 is_eliding = False
157 elide_count = 0
158 last_elided_line = None
159 for line, line_in_prev in zip(curr_traceback_list, prev_traceback_list):
160 if line == line_in_prev:
161 if is_eliding:
162 elide_count += 1
163 last_elided_line = line
164 else:
165 output.append(line)
166 is_eliding = True
167 elide_count = 0
168 else:
169 if is_eliding:
170 if elide_count > 0:
171 output.extend([
172 "[elided %d identical lines from previous traceback]\n" %
173 (elide_count - 1,), last_elided_line
174 ])
175 is_eliding = False
176 output.extend(line)
178 # pylint: disable=protected-access
179 original_op = original_op._original_op
180 # pylint: enable=protected-access
181 return "".join(output)
182 else:
183 return self.message
186OK = error_codes_pb2.OK
187tf_export("errors.OK").export_constant(__name__, "OK")
188CANCELLED = error_codes_pb2.CANCELLED
189tf_export("errors.CANCELLED").export_constant(__name__, "CANCELLED")
190UNKNOWN = error_codes_pb2.UNKNOWN
191tf_export("errors.UNKNOWN").export_constant(__name__, "UNKNOWN")
192INVALID_ARGUMENT = error_codes_pb2.INVALID_ARGUMENT
193tf_export("errors.INVALID_ARGUMENT").export_constant(__name__,
194 "INVALID_ARGUMENT")
195DEADLINE_EXCEEDED = error_codes_pb2.DEADLINE_EXCEEDED
196tf_export("errors.DEADLINE_EXCEEDED").export_constant(__name__,
197 "DEADLINE_EXCEEDED")
198NOT_FOUND = error_codes_pb2.NOT_FOUND
199tf_export("errors.NOT_FOUND").export_constant(__name__, "NOT_FOUND")
200ALREADY_EXISTS = error_codes_pb2.ALREADY_EXISTS
201tf_export("errors.ALREADY_EXISTS").export_constant(__name__, "ALREADY_EXISTS")
202PERMISSION_DENIED = error_codes_pb2.PERMISSION_DENIED
203tf_export("errors.PERMISSION_DENIED").export_constant(__name__,
204 "PERMISSION_DENIED")
205UNAUTHENTICATED = error_codes_pb2.UNAUTHENTICATED
206tf_export("errors.UNAUTHENTICATED").export_constant(__name__, "UNAUTHENTICATED")
207RESOURCE_EXHAUSTED = error_codes_pb2.RESOURCE_EXHAUSTED
208tf_export("errors.RESOURCE_EXHAUSTED").export_constant(__name__,
209 "RESOURCE_EXHAUSTED")
210FAILED_PRECONDITION = error_codes_pb2.FAILED_PRECONDITION
211tf_export("errors.FAILED_PRECONDITION").export_constant(__name__,
212 "FAILED_PRECONDITION")
213ABORTED = error_codes_pb2.ABORTED
214tf_export("errors.ABORTED").export_constant(__name__, "ABORTED")
215OUT_OF_RANGE = error_codes_pb2.OUT_OF_RANGE
216tf_export("errors.OUT_OF_RANGE").export_constant(__name__, "OUT_OF_RANGE")
217UNIMPLEMENTED = error_codes_pb2.UNIMPLEMENTED
218tf_export("errors.UNIMPLEMENTED").export_constant(__name__, "UNIMPLEMENTED")
219INTERNAL = error_codes_pb2.INTERNAL
220tf_export("errors.INTERNAL").export_constant(__name__, "INTERNAL")
221UNAVAILABLE = error_codes_pb2.UNAVAILABLE
222tf_export("errors.UNAVAILABLE").export_constant(__name__, "UNAVAILABLE")
223DATA_LOSS = error_codes_pb2.DATA_LOSS
224tf_export("errors.DATA_LOSS").export_constant(__name__, "DATA_LOSS")
227@tf_export("errors.CancelledError")
228class CancelledError(OpError):
229 """Raised when an operation is cancelled.
231 For example, a long-running operation e.g.`tf.queue.QueueBase.enqueue`, or a
232 `tf.function` call may be cancelled by either running another operation e.g.
233 `tf.queue.QueueBase.close` or a remote worker failure.
235 This long-running operation will fail by raising `CancelledError`.
237 Example:
238 >>> q = tf.queue.FIFOQueue(10, tf.float32, ((),))
239 >>> q.enqueue((10.0,))
240 >>> q.close()
241 >>> q.enqueue((10.0,))
242 Traceback (most recent call last):
243 ...
244 CancelledError: ...
246 """
248 def __init__(self, node_def, op, message, *args):
249 """Creates a `CancelledError`."""
250 super(CancelledError, self).__init__(node_def, op, message, CANCELLED,
251 *args)
254@tf_export("errors.UnknownError")
255class UnknownError(OpError):
256 """Unknown error.
258 An example of where this error may be returned is if a Status value
259 received from another address space belongs to an error-space that
260 is not known to this address space. Also, errors raised by APIs that
261 do not return enough error information may be converted to this
262 error.
263 """
265 def __init__(self, node_def, op, message, *args):
266 """Creates an `UnknownError`."""
267 super(UnknownError, self).__init__(node_def, op, message, UNKNOWN, *args)
270@tf_export("errors.InvalidArgumentError")
271class InvalidArgumentError(OpError):
272 """Raised when an operation receives an invalid argument.
274 This error is typically raised when an op receives mismatched arguments.
276 Example:
278 >>> tf.reshape([1, 2, 3], (2,))
279 Traceback (most recent call last):
280 ...
281 InvalidArgumentError: ...
282 """
284 def __init__(self, node_def, op, message, *args):
285 """Creates an `InvalidArgumentError`."""
286 super(InvalidArgumentError, self).__init__(node_def, op, message,
287 INVALID_ARGUMENT, *args)
290@tf_export("errors.DeadlineExceededError")
291class DeadlineExceededError(OpError):
292 """Raised when a deadline expires before an operation could complete.
294 This exception is not currently used.
295 """
297 def __init__(self, node_def, op, message, *args):
298 """Creates a `DeadlineExceededError`."""
299 super(DeadlineExceededError, self).__init__(node_def, op, message,
300 DEADLINE_EXCEEDED, *args)
303@tf_export("errors.NotFoundError")
304class NotFoundError(OpError):
305 """Raised when a requested entity (e.g., a file or directory) was not found.
307 For example, running the
308 `tf.WholeFileReader.read`
309 operation could raise `NotFoundError` if it receives the name of a file that
310 does not exist.
311 """
313 def __init__(self, node_def, op, message, *args):
314 """Creates a `NotFoundError`."""
315 super(NotFoundError, self).__init__(node_def, op, message, NOT_FOUND, *args)
318@tf_export("errors.AlreadyExistsError")
319class AlreadyExistsError(OpError):
320 """Raised when an entity that we attempted to create already exists.
322 An API raises this this error to avoid overwriting an existing resource,
323 value, etc. Calling a creation API multiple times with the same arguments
324 could raise this error if the creation API is not idempotent.
326 For example, running an operation that saves a file
327 (e.g. `tf.saved_model.save`)
328 could potentially raise this exception if an explicit filename for an
329 existing file was passed.
330 """
332 def __init__(self, node_def, op, message, *args):
333 """Creates an `AlreadyExistsError`."""
334 super(AlreadyExistsError, self).__init__(node_def, op, message,
335 ALREADY_EXISTS, *args)
338@tf_export("errors.PermissionDeniedError")
339class PermissionDeniedError(OpError):
340 """Raised when the caller does not have permission to run an operation.
342 For example, running the
343 `tf.WholeFileReader.read`
344 operation could raise `PermissionDeniedError` if it receives the name of a
345 file for which the user does not have the read file permission.
346 """
348 def __init__(self, node_def, op, message, *args):
349 """Creates a `PermissionDeniedError`."""
350 super(PermissionDeniedError, self).__init__(node_def, op, message,
351 PERMISSION_DENIED, *args)
354@tf_export("errors.UnauthenticatedError")
355class UnauthenticatedError(OpError):
356 """Raised when the request does not have valid authentication credentials.
358 This exception is not currently used.
359 """
361 def __init__(self, node_def, op, message, *args):
362 """Creates an `UnauthenticatedError`."""
363 super(UnauthenticatedError, self).__init__(node_def, op, message,
364 UNAUTHENTICATED, *args)
367@tf_export("errors.ResourceExhaustedError")
368class ResourceExhaustedError(OpError):
369 """Raised when some resource has been exhausted while running operation.
371 For example, this error might be raised if a per-user quota is
372 exhausted, or perhaps the entire file system is out of space. If running into
373 `ResourceExhaustedError` due to out of memory (OOM), try to use smaller batch
374 size or reduce dimension size of model weights.
375 """
377 def __init__(self, node_def, op, message, *args):
378 """Creates a `ResourceExhaustedError`."""
379 super(ResourceExhaustedError, self).__init__(node_def, op, message,
380 RESOURCE_EXHAUSTED, *args)
383@tf_export("errors.FailedPreconditionError")
384class FailedPreconditionError(OpError):
385 """Raised when some prerequisites are not met when running an operation.
387 This typically indicates that system is not in state to execute the operation
388 and requires preconditions to be met before successfully executing current
389 operation.
391 For example, this exception is commonly raised when running an operation
392 that reads a `tf.Variable` before it has been initialized.
393 """
395 def __init__(self, node_def, op, message, *args):
396 """Creates a `FailedPreconditionError`."""
397 super(FailedPreconditionError, self).__init__(node_def, op, message,
398 FAILED_PRECONDITION, *args)
401@tf_export("errors.AbortedError")
402class AbortedError(OpError):
403 """Raised when an operation was aborted, typically due to a concurrent action.
405 For example, running a
406 `tf.queue.QueueBase.enqueue`
407 operation may raise `AbortedError` if a
408 `tf.queue.QueueBase.close` operation
409 previously ran.
410 """
412 def __init__(self, node_def, op, message, *args):
413 """Creates an `AbortedError`."""
414 super(AbortedError, self).__init__(node_def, op, message, ABORTED, *args)
417@tf_export("errors.OutOfRangeError")
418class OutOfRangeError(OpError):
419 """Raised when an operation iterates past the valid range.
421 Unlike `InvalidArgumentError`, this error indicates a problem may be fixed if
422 the system state changes. For example, if a list grows and the operation is
423 now within the valid range. `OutOfRangeError` overlaps with
424 `FailedPreconditionError` and should be preferred as the more specific error
425 when iterating or accessing a range.
427 For example, iterating a TF dataset past the last item in the dataset will
428 raise this error.
429 """
431 def __init__(self, node_def, op, message, *args):
432 """Creates an `OutOfRangeError`."""
433 super(OutOfRangeError, self).__init__(node_def, op, message, OUT_OF_RANGE,
434 *args)
437@tf_export("errors.UnimplementedError")
438class UnimplementedError(OpError):
439 """Raised when an operation has not been implemented.
441 Some operations may raise this error when passed otherwise-valid
442 arguments that it does not currently support. For example, running
443 the `tf.nn.max_pool2d` operation
444 would raise this error if pooling was requested on the batch dimension,
445 because this is not yet supported.
446 """
448 def __init__(self, node_def, op, message, *args):
449 """Creates an `UnimplementedError`."""
450 super(UnimplementedError, self).__init__(node_def, op, message,
451 UNIMPLEMENTED, *args)
454@tf_export("errors.InternalError")
455class InternalError(OpError):
456 """Raised when the system experiences an internal error.
458 This exception is raised when some invariant expected by the runtime
459 has been broken. Catching this exception is not recommended.
460 """
462 def __init__(self, node_def, op, message, *args):
463 """Creates an `InternalError`."""
464 super(InternalError, self).__init__(node_def, op, message, INTERNAL, *args)
467@tf_export("errors.UnavailableError")
468class UnavailableError(OpError):
469 """Raised when the runtime is currently unavailable.
471 This exception is not currently used.
472 """
474 def __init__(self, node_def, op, message, *args):
475 """Creates an `UnavailableError`."""
476 super(UnavailableError, self).__init__(node_def, op, message, UNAVAILABLE,
477 *args)
480@tf_export("errors.DataLossError")
481class DataLossError(OpError):
482 """Raised when unrecoverable data loss or corruption is encountered.
484 This could be due to:
485 * A truncated file.
486 * A corrupted file.
487 * Specifying the wrong data format.
489 For example, this may be raised by running a
490 `tf.WholeFileReader.read`
491 operation, if the file is truncated while it is being read.
492 """
494 def __init__(self, node_def, op, message, *args):
495 """Creates a `DataLossError`."""
496 super(DataLossError, self).__init__(node_def, op, message, DATA_LOSS, *args)
499_CODE_TO_EXCEPTION_CLASS = {
500 CANCELLED: CancelledError,
501 UNKNOWN: UnknownError,
502 INVALID_ARGUMENT: InvalidArgumentError,
503 DEADLINE_EXCEEDED: DeadlineExceededError,
504 NOT_FOUND: NotFoundError,
505 ALREADY_EXISTS: AlreadyExistsError,
506 PERMISSION_DENIED: PermissionDeniedError,
507 UNAUTHENTICATED: UnauthenticatedError,
508 RESOURCE_EXHAUSTED: ResourceExhaustedError,
509 FAILED_PRECONDITION: FailedPreconditionError,
510 ABORTED: AbortedError,
511 OUT_OF_RANGE: OutOfRangeError,
512 UNIMPLEMENTED: UnimplementedError,
513 INTERNAL: InternalError,
514 UNAVAILABLE: UnavailableError,
515 DATA_LOSS: DataLossError,
516}
518_pywrap_py_exception_registry.PyExceptionRegistry_Init(_CODE_TO_EXCEPTION_CLASS)
520_EXCEPTION_CLASS_TO_CODE = {
521 class_: code for code, class_ in _CODE_TO_EXCEPTION_CLASS.items()
522}
525@tf_export(v1=["errors.exception_type_from_error_code"])
526def exception_type_from_error_code(error_code):
527 return _CODE_TO_EXCEPTION_CLASS[error_code]
530@tf_export(v1=["errors.error_code_from_exception_type"])
531def error_code_from_exception_type(cls):
532 try:
533 return _EXCEPTION_CLASS_TO_CODE[cls]
534 except KeyError:
535 warnings.warn("Unknown class exception")
536 return UnknownError(None, None, "Unknown class exception", None)
539def _make_specific_exception(node_def, op, message, error_code):
540 try:
541 exc_type = exception_type_from_error_code(error_code)
542 return exc_type(node_def, op, message)
543 except KeyError:
544 warnings.warn("Unknown error code: %d" % error_code)
545 return UnknownError(node_def, op, message, error_code)
548# Named like a function for backwards compatibility with the
549# @tf_contextlib.contextmanager version, which was switched to a class to avoid
550# some object creation overhead.
551# TODO(b/77295559): expand use of TF_Status* SWIG typemap and deprecate this.
552@tf_export(v1=["errors.raise_exception_on_not_ok_status"]) # pylint: disable=invalid-name
553class raise_exception_on_not_ok_status(object):
554 """Context manager to check for C API status."""
556 def __enter__(self):
557 self.status = c_api_util.ScopedTFStatus()
558 return self.status.status
560 def __exit__(self, type_arg, value_arg, traceback_arg):
561 try:
562 if c_api.TF_GetCode(self.status.status) != 0:
563 raise _make_specific_exception(
564 None, None, compat.as_text(c_api.TF_Message(self.status.status)),
565 c_api.TF_GetCode(self.status.status))
566 # Delete the underlying status object from memory otherwise it stays alive
567 # as there is a reference to status from this from the traceback due to
568 # raise.
569 finally:
570 del self.status
571 return False # False values do not suppress exceptions