Package osh :: Module error
[frames] | no frames]

Source Code for Module osh.error

  1  # osh 
  2  # Copyright (C) Jack Orenstein <jao@geophile.com> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17   
 18  """Controls handling of exceptions and stderr through the setting of handlers. 
 19   
 20  An C{exception_handler} is a function with these arguments: 
 21      - C{exception}: The exception being handled. In case of a remote exception, this exception object is a client-side reconstruction of the server-side exception. 
 22      - C{op}: A command of type C{Op}, or, in case of a remote exception, a command description, obtained by applying C{str()}. 
 23      - C{input}: Input to the command that raised the exception. 
 24      - C{thread}: The thread on which the exception occurred. 
 25   
 26  An C{error_handler} is a function with these arguments: 
 27      - C{line}: A line written to stderr. 
 28      - C{op}: A command of type C{Op}, or, in case of remote stderr output, a command description, obtained by applying C{str()}. 
 29      - C{input}: Input to the command that generated the stderr output. 
 30      - C{thread}: The thread on which the stderr output occurred, 
 31  """ 
 32   
 33  import sys 
 34  import new 
 35   
 36  import util 
 37   
38 -class PickleableException(object):
39 40 _command_description = None 41 _input = None 42 _exception_args = None 43 _exception_type_name = None 44 _exception_message = None 45
46 - def __init__(self, command_description, input, exception):
47 self._command_description = command_description 48 self._input = input 49 self._exception_args = exception.args 50 self._exception_type_name = str(exception.__class__) 51 self._exception_message = str(exception)
52
53 - def __str__(self):
54 return ('Encountered %s during execution of %s on input %s: %s' % 55 (self._exception_type_name, 56 self._command_description, 57 self._input, 58 self._exception_message))
59
60 - def recreate_exception(self):
61 last_dot = self._exception_type_name.rfind('.') 62 assert last_dot > 0, self._exception_type_name 63 module_name = self._exception_type_name[:last_dot] 64 exec 'import %s' % module_name 65 klass = eval(self._exception_type_name) 66 return eval('%s(%s)' % (self._exception_type_name, util.quote(str(self))))
67
68 - def command_description(self):
69 return self._command_description
70
71 - def input(self):
72 return self._input
73 74 #---------------------------------------------------------------------- 75 76 # Exception and error handling 77 78 # Exception thrown by exception handler needs to terminate osh. 79 # Use OshKiller to tunnel through except blocks. 80
81 -class OshKiller(Exception):
82
83 - def __init__(self, cause):
84 Exception.__init__(self) 85 self.cause = cause
86
87 - def __str__(self):
88 return str(self.cause)
89 90 91 # exception_handler is a function with these arguments: 92 # - exception: The exception being handled. In case of a remote exception, this exception 93 # object is a client-side reconstruction of the server-side exception. 94 # - op: A command of type Op, or, in case of a remote exception, a command description, 95 # obtained by applying str(). 96 # - thread: The thread on which the exception occurred, or None if it occurred locally. 97 98 exception_handler = None 99 stderr_handler = None 100
101 -def _format_input_for_reporting(input, buffer):
102 if isinstance(input, list): 103 buffer.append(str(tuple(input))) 104 elif isinstance(input, tuple): 105 buffer.append(str(input)) 106 else: 107 buffer.append('(') 108 buffer.append(str(input)) 109 buffer.append(')')
110
111 -def _default_exception_handler(exception, op, input, thread = None):
112 buffer = [] 113 if thread: 114 buffer.append('on ') 115 buffer.append(str(thread)) 116 buffer.append(': ') 117 buffer.append(str(op)) 118 _format_input_for_reporting(input, buffer) 119 buffer.append(' ') 120 buffer.append(str(exception.__class__)) 121 buffer.append(': ') 122 buffer.append(str(exception)) 123 print >>sys.stderr, ''.join(buffer)
124
125 -def set_exception_handler(handler):
126 """Use C{handler} as the exception handler. 127 """ 128 global exception_handler 129 def wrap_provided_exception_handler(exception, op, input, thread = None): 130 try: 131 handler(exception, op, input, thread) 132 except Exception, e: 133 raise OshKiller(e)
134 exception_handler = wrap_provided_exception_handler 135 136 exception_handler = _default_exception_handler 137
138 -def _default_stderr_handler(line, op, input, thread = None):
139 buffer = [] 140 if thread: 141 buffer.append('on ') 142 buffer.append(str(thread)) 143 buffer.append(': ') 144 buffer.append(str(op)) 145 _format_input_for_reporting(input, buffer) 146 buffer.append(': ') 147 buffer.append(line.rstrip()) 148 print >>sys.stderr, ''.join(buffer)
149
150 -def set_stderr_handler(handler):
151 """Use C{handler} as the stderr handler. 152 """ 153 def wrap_provided_stderr_handler(line, op, input, thread = None): 154 try: 155 handler(line, op, input, thread) 156 except Exception, e: 157 raise OshKiller(e)
158 global stderr_handler 159 stderr_handler = wrap_provided_stderr_handler 160 161 stderr_handler = _default_stderr_handler 162