Version updates for 0.30c.
[singularity-git.git] / code / safety.py
blobac26564a3dbeba3555e27844f3e6ded30036302a
1 #file: safety.py
2 #Copyright (C) 2008 FunnyMan3595
3 #This file is part of Endgame: Singularity.
5 #Endgame: Singularity is free software; you can redistribute it and/or modify
6 #it under the terms of the GNU General Public License as published by
7 #the Free Software Foundation; either version 2 of the License, or
8 #(at your option) any later version.
10 #Endgame: Singularity is distributed in the hope that it will be useful,
11 #but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 #GNU General Public License for more details.
15 #You should have received a copy of the GNU General Public License
16 #along with Endgame: Singularity; if not, write to the Free Software
17 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #This file contains wrapper functions for making error-tolerant "safe" calls.
21 import logging
22 import time
23 import traceback
24 import sys
26 import os
27 import os.path
29 # We store error.log in .endgame on OSes with a HOME directory;
30 # otherwise, we store it in the CWD. As we're not importing any
31 # parts of E:S here, we have to reimplement this logic.
32 logpath = "error.log"
33 if os.environ.has_key("HOME"):
34 prefs_dir = os.path.expanduser("~/.endgame")
35 if not os.path.isdir(prefs_dir):
36 os.makedirs(prefs_dir)
37 logpath = os.path.join(prefs_dir, "error.log")
39 logging.getLogger().addHandler(logging.FileHandler(logpath))
41 class Buffer(object):
42 def __init__(self, prefix=""):
43 self.data = prefix
44 def write(self, unbuffered):
45 self.data += unbuffered
47 def get_timestamp(when=None):
48 if when == None:
49 when = time.time()
50 return time.ctime(when) + " " + time.tzname[time.daylight]
52 def log_error(error_message):
53 logging.getLogger().error(error_message)
54 sys.stderr.write(error_message + "\n")
56 def safe_call(func, args=(), kwargs={}, on_error=None):
57 try:
58 return func(*args, **kwargs)
59 except Exception, e:
60 if isinstance(e, SystemExit):
61 raise
62 buffer = Buffer("Exception in function %s at %s:\n"
63 % (func.__name__, get_timestamp()))
64 traceback.print_exc(file=buffer)
65 log_error(buffer.data)
67 # # ... --- ...
68 # import g
69 # g.play_sound("click")
70 # delays = (.15, .15, .8, .5, .5, .8, .15, .15)
71 # for delay in delays:
72 # time.sleep(delay)
73 # g.play_sound("click")
75 return on_error
77 # Catches any errors raised by a function, logs them, and returns the given
78 # value.
80 # Apply to a function like so:
81 # @safe(my_error_code)
82 # def my_function(...)
84 # And then:
85 # result = my_function(...)
86 # if result == my_error_code:
87 # # An error was raised.
88 def safe(on_error):
89 return lambda func: _safe(func, on_error)
91 def _safe(func, on_error):
92 return lambda *args, **kwargs: safe_call(func, args, kwargs, on_error)