diff --git a/src/error.c b/src/error.c
index abf39b52fe0e36da6dd13b713754f7b36d813ab9..1433f6e1e516fe619b16f0cdbb7b5b011722aeb9 100644
--- a/src/error.c
+++ b/src/error.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: error.c,v 1.155 2008/05/24 12:28:58 mast Exp $
+|| $Id: error.c,v 1.156 2008/05/27 01:39:44 mast Exp $
 */
 
 #define NO_PIKE_SHORTHAND
@@ -681,6 +681,8 @@ PMOD_EXPORT DECLSPEC(noreturn) void debug_fatal(const char *fmt, ...) ATTRIBUTE(
  *! remains the same in the rethrown error.
  */
 
+#define GENERIC_ERROR_THIS ((struct generic_error_struct *)CURRENT_STORAGE)
+
 #define ERR_DECLARE
 #include "errors.h"
 
@@ -799,27 +801,45 @@ static void f_error_backtrace(INT32 args)
  */
 static void f_error__sprintf(INT32 args)
 {
-  struct program *p = Pike_fp->current_object->prog;
-  /* FIXME: What about obscure overloadings? */
-  int i = find_identifier("error_type", p);
-  struct identifier *id = ID_FROM_INT(p, i);
   int mode = 0;
+
   if(args>0 && Pike_sp[-args].type == PIKE_T_INT)
     mode = Pike_sp[-args].u.integer;
   pop_n_elems(args);
+
   if(mode != 'O') {
     push_undefined();
     return;
   }
-  push_constant_text ("Error.");
-  push_svalue(&PROG_FROM_INT(p, i)->constants[id->func.offset].sval);
+
+  {
+    struct program *p = Pike_fp->current_object->prog;
+    int i;
+    struct pike_string *error_name_str;
+    /* error_name is the name the error program wants in printouts
+     * like this. To still let inheriting programs fall back to
+     * describe_program if they don't provide it, we make it private
+     * in the base error classes and allow us to see private
+     * identifiers here. */
+    MAKE_CONST_STRING (error_name_str, "error_name");
+    i = really_low_find_shared_string_identifier (error_name_str, p,
+						  SEE_PRIVATE);
+    if (i != -1)
+      push_svalue (&PROG_FROM_INT (p, i)->
+		   constants[ID_FROM_INT (p, i)->func.offset].sval);
+    else {
+      ref_push_program (p);
+      SAFE_APPLY_MASTER ("describe_program", 1);
+    }
+  }
+
   push_constant_text("(%O)");
   if(GENERIC_ERROR_THIS->error_message)
     ref_push_string(GENERIC_ERROR_THIS->error_message);
   else
     push_int(0);
   f_sprintf(2);
-  f_add(3);
+  f_add(2);
 }
 
 /*! @decl int(0..1) _is_type(string t)
diff --git a/src/errors.h b/src/errors.h
index f7cc9db5747265f704993e2a0fda728e7f4f9ad9..7e0552df01ccc34ad772771996297662717ab8e1 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: errors.h,v 1.38 2008/05/23 19:39:06 grubba Exp $
+|| $Id: errors.h,v 1.39 2008/05/27 01:39:44 mast Exp $
 */
 
 #ifdef ERR_DECLARE
@@ -40,6 +40,7 @@
     start_new_program();				\
     INHERIT						\
     add_string_constant("error_type", #SCNAME, 0);	\
+    add_string_constant ("error_name", "Error." #SCNAME, ID_PRIVATE|ID_USED); \
     add_integer_constant("is_" #NAME "_error",1,0);	\
     PIKE_CONCAT(NAME,_error_program)=end_program();	\
     add_program_constant( #SCNAME "Error",PIKE_CONCAT(NAME,_error_program),0); \
@@ -125,8 +126,6 @@ DECLARE_ERROR(generic, Generic, EMPTY ,
   ERR_FUNC("create",f_error_create,tFunc(tStr tOr(tVoid,tArr(tMixed)),tVoid),ID_STATIC)
 )
 
-#define GENERIC_ERROR_THIS ((struct generic_error_struct *)CURRENT_STORAGE)
-
 DECLARE_ERROR(index, Index,
 	      ERR_INHERIT(generic),
   ERR_VAR(struct svalue, tMix, PIKE_T_MIXED, value)