diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
index 28d1e04..cef4dbb 100644
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -84,6 +84,11 @@ from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
 from IPython.utils.warn import warn, error
 import IPython.core.hooks
 
+try:
+    from IPython.parallel.error import RemoteError
+except ImportError:
+    class RemoteError(Exception): pass
+
 #-----------------------------------------------------------------------------
 # Globals
 #-----------------------------------------------------------------------------
@@ -1711,6 +1716,10 @@ class InteractiveShell(SingletonConfigurable):
                 self.showsyntaxerror(filename)
             elif etype is UsageError:
                 self.write_err("UsageError: %s" % value)
+            elif issubclass(etype, RemoteError):
+                # IPython.parallel remote exceptions.
+                # Draw the remote traceback, not the local one.
+                self._showtraceback(etype, value, value.render_traceback())
             else:
                 if exception_only:
                     stb = ['An exception has occurred, use %tb to see '
diff --git a/IPython/parallel/error.py b/IPython/parallel/error.py
index abfb578..910c422 100644
--- a/IPython/parallel/error.py
+++ b/IPython/parallel/error.py
@@ -188,11 +188,17 @@ class RemoteError(KernelError):
         return "<Remote[%s]:%s(%s)>"%(engineid, self.ename, self.evalue)
 
     def __str__(self):
-        sig = "%s(%s)"%(self.ename, self.evalue)
-        if self.traceback:
-            return sig + '\n' + self.traceback
-        else:
-            return sig
+        return "%s(%s)" % (self.ename, self.evalue)
+    
+    def render_traceback(self):
+        """render traceback to a list of lines"""
+        return (self.traceback or "No traceback available").splitlines()
+
+    def print_traceback(self, excid=None):
+        """print my traceback"""
+        print('\n'.join(self.render_traceback()))
+
+    
 
 
 class TaskRejectError(KernelError):
@@ -243,21 +249,28 @@ class CompositeError(RemoteError):
 
     def __repr__(self):
         return "CompositeError(%i)"%len(self.elist)
-
-    def print_tracebacks(self, excid=None):
+    
+    def render_traceback(self, excid=None):
+        """render one or all of my tracebacks to a list of lines"""
+        lines = []
         if excid is None:
             for (en,ev,etb,ei) in self.elist:
-                print (self._get_engine_str(ei))
-                print (etb or 'No traceback available')
-                print ()
+                lines.append(self._get_engine_str(ei))
+                lines.extend((etb or 'No traceback available').splitlines())
+                lines.append('')
         else:
             try:
                 en,ev,etb,ei = self.elist[excid]
             except:
                 raise IndexError("an exception with index %i does not exist"%excid)
             else:
-                print (self._get_engine_str(ei))
-                print (etb or 'No traceback available')
+                lines.append(self._get_engine_str(ei))
+                lines.extend((etb or 'No traceback available').splitlines())
+        
+        return lines
+    
+    def print_traceback(self, excid=None):
+        print('\n'.join(self.render_traceback(excid)))
 
     def raise_exception(self, excid=0):
         try: