diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index 13efa4ec58b5b1ab65b2749450040bb47b7fa78d..d6bec005fee5376cae92507d651f75351b7bb0b9 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -222,6 +222,11 @@ class Program(object):
         try:
             return build_func()
         except _cl.RuntimeError as e:
+            from pytools import Record
+
+            class ErrorRecord(Record):
+                pass
+
             what = e.what
             if options:
                 what = what + "\n(options: %s)" % " ".join(options)
@@ -236,7 +241,14 @@ class Program(object):
 
                 what = what + "\n(source saved as %s)" % srcfile.name
 
-            err = _cl.RuntimeError(msg=what, routine=e.routine, code=e.code)
+            code = e.code
+            routine = e.routine
+
+            err = _cl.RuntimeError(
+                    ErrorRecord(
+                        what=lambda: what,
+                        code=lambda: code,
+                        routine=lambda: routine))
 
         # Python 3.2 outputs the whole list of currently active exceptions
         # This serves to remove one (redundant) level from that nesting.
@@ -421,11 +433,22 @@ def _add_functionality():
         try:
             self._build(options=options, devices=devices)
         except Error as e:
+            from pytools import Record
+
+            class ErrorRecord(Record):
+                pass
+
             what = e.what + "\n\n" + (75*"="+"\n").join(
                     "Build on %s:\n\n%s" % (dev, log)
                     for dev, log in self._get_build_logs())
+            code = e.code
+            routine = e.routine
 
-            err = _cl.RuntimeError(msg=what, routine=e.routine, code=e.code)
+            err = _cl.RuntimeError(
+                    ErrorRecord(
+                        what=lambda: what,
+                        code=lambda: code,
+                        routine=lambda: routine))
 
         if err is not None:
             # Python 3.2 outputs the whole list of currently active exceptions
@@ -710,37 +733,37 @@ def _add_functionality():
 
     # }}}
 
-    # # {{{ Error
-
-    # def error_str(self):
-    #     val = self.args[0]
-    #     try:
-    #         val.routine
-    #     except AttributeError:
-    #         return str(val)
-    #     else:
-    #         result = "%s failed: %s" % (val.routine(),
-    #                 status_code.to_string(val.code(), "<unknown error %d>")
-    #                 .lower().replace("_", " "))
-    #         if val.what():
-    #             result += " - " + val.what()
-    #         return result
-
-    # def error_code(self):
-    #     return self.args[0].code()
-
-    # def error_routine(self):
-    #     return self.args[0].routine()
-
-    # def error_what(self):
-    #     return self.args[0].what()
-
-    # Error.__str__ = error_str
-    # Error.code = property(error_code)
-    # Error.routine = property(error_routine)
-    # Error.what = property(error_what)
-
-    # # }}}
+    # {{{ Error
+
+    def error_str(self):
+        val = self.args[0]
+        try:
+            val.routine
+        except AttributeError:
+            return str(val)
+        else:
+            result = "%s failed: %s" % (val.routine(),
+                    status_code.to_string(val.code(), "<unknown error %d>")
+                    .lower().replace("_", " "))
+            if val.what():
+                result += " - " + val.what()
+            return result
+
+    def error_code(self):
+        return self.args[0].code()
+
+    def error_routine(self):
+        return self.args[0].routine()
+
+    def error_what(self):
+        return self.args[0].what()
+
+    Error.__str__ = error_str
+    Error.code = property(error_code)
+    Error.routine = property(error_routine)
+    Error.what = property(error_what)
+
+    # }}}
 
     # if _cl.have_gl():
     #     def gl_object_get_gl_object(self):
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 0f5023256fff212b52e50bb7cfd94d669f59c121..9263287aafea301976ae8db0aec00196de9221a0 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -428,12 +428,24 @@ del _constant_callback
 # {{{ exceptions
 
 class Error(Exception):
-    def __init__(self, msg='', code=0, routine=''):
-        self.routine = routine
-        assert isinstance(code, int)
-        self.code = code
-        self.what = msg
-        super(Error, self).__init__(msg)
+    class __ErrorRecord(object):
+        __slots__ = ('_routine', '_code', '_what')
+        def __init__(self, msg='', code=0, routine=''):
+            self._routine = routine
+            assert isinstance(code, int)
+            self._code = code
+            self._what = msg
+        def routine(self):
+            return self._routine
+        def code(self):
+            return self._code
+        def what(self):
+            return self._what
+    def __init__(self, *a, **kw):
+        if len(a) == 1 and not kw and hasattr(a[0], 'what'):
+            super(Error, self).__init__(a[0])
+        else:
+            super(Error, self).__init__(self.__ErrorRecord(*a, **kw))
 
 
 class MemoryError(Error):