[[[
Make help work even if some RA modules fail to initialize.

* subversion/libsvn_ra/ra_loader.c
  (svn_ra_print_modules): If some modules fail to initialize,
    then just output the error messages as their description,
    instead of propagating the error to the caller.
  (print_module): New function.
]]]

=== subversion/libsvn_ra/ra_loader.c
==================================================================
--- subversion/libsvn_ra/ra_loader.c	(revision 16466)
+++ subversion/libsvn_ra/ra_loader.c	(local)
@@ -645,50 +645,91 @@
 
 
 
+/* Load the RA library specified by *DEFN, and append a description of
+   it to *OUTPUT.  This is separate from svn_ra_print_modules to
+   simplify error handling.  If this returns an error, the caller may
+   assume it didn't output anything.  */
+static svn_error_t *
+print_module (svn_stringbuf_t *output,
+              const struct ra_lib_defn *defn,
+              apr_pool_t *pool)
+{
+  const char * const *schemes;
+  svn_ra__init_func_t initfunc;
+  const svn_ra__vtable_t *vtable;
+  char *line;
+
+  initfunc = defn->initfunc;
+  if (! initfunc)
+    SVN_ERR (load_ra_module (&initfunc, NULL, defn->ra_name,
+                             pool));
+
+  if (initfunc)
+    {
+      SVN_ERR (initfunc (svn_ra_version(), &vtable, pool));
+
+      SVN_ERR (check_ra_version (vtable->get_version (), defn->ra_name));
+
+      line = apr_psprintf (pool, "* ra_%s : %s\n",
+                           defn->ra_name,
+                           vtable->get_description());
+      svn_stringbuf_appendcstr (output, line);
+
+      for (schemes = vtable->get_schemes(pool); *schemes != NULL;
+           ++schemes)
+        {
+          line = apr_psprintf (pool, _("  - handles '%s' scheme\n"),
+                               *schemes);
+          svn_stringbuf_appendcstr (output, line);
+        }
+    }
+
+  return SVN_NO_ERROR;
+}  
+
 svn_error_t *
 svn_ra_print_modules (svn_stringbuf_t *output,
                       apr_pool_t *pool)
 {
   const struct ra_lib_defn *defn;
-  const char * const *schemes;
-  svn_ra__init_func_t initfunc;
-  const svn_ra__vtable_t *vtable;
+  svn_stringbuf_t *failure_footer = svn_stringbuf_create ("", pool);
   apr_pool_t *iterpool = svn_pool_create (pool);
 
   for (defn = ra_libraries; defn->ra_name != NULL; ++defn)
     {
-      char *line;
+      svn_error_t *error;
 
       svn_pool_clear (iterpool);
 
-      initfunc = defn->initfunc;
-      if (! initfunc)
-        SVN_ERR (load_ra_module (&initfunc, NULL, defn->ra_name,
-                                 iterpool));
-
-      if (initfunc)
+      error = print_module (output, defn, iterpool);
+      if (error)
         {
-          SVN_ERR (initfunc (svn_ra_version(), &vtable, iterpool));
+          char *line;
+          svn_error_t *trace;
 
-          SVN_ERR (check_ra_version (vtable->get_version (), defn->ra_name));
-
-          line = apr_psprintf (iterpool, "* ra_%s : %s\n",
-                               defn->ra_name,
-                               vtable->get_description());
-          svn_stringbuf_appendcstr (output, line);
-
-          for (schemes = vtable->get_schemes(iterpool); *schemes != NULL;
-               ++schemes)
+          line = apr_psprintf (iterpool, "* ra_%s\n",
+                               defn->ra_name);
+          svn_stringbuf_appendcstr (failure_footer, line);
+          /* Cannot use svn_handle_error2, because it outputs to a FILE.  */
+          for (trace = error; trace != NULL; trace = trace->child)
             {
-              line = apr_psprintf (iterpool, _("  - handles '%s' scheme\n"),
-                                   *schemes);
-              svn_stringbuf_appendcstr (output, line);
+              line = apr_psprintf (iterpool, "  - %s\n", trace->message);
+              svn_stringbuf_appendcstr (failure_footer, line);
             }
         }
+      svn_error_clear (error);
     }
 
   svn_pool_destroy (iterpool);
 
+  if (! svn_stringbuf_isempty (failure_footer))
+    {
+      svn_stringbuf_appendcstr (output, _("\nThe following RA modules exist"
+                                          " but cannot be used:\n\n"));
+      svn_stringbuf_appendbytes (output, failure_footer->data,
+                                 failure_footer->len);
+    }
+
   return SVN_NO_ERROR;
 }
 

