Browse Source

Don't propagate service exception from dependency directly

Rather than let the original exception bubble up if a dependency fails
to load for some reason, log the error and then throw a general
service_load_exc. This allows better error reporting.
Davin McCall 1 year ago
parent
commit
4f07b49c50
1 changed files with 26 additions and 3 deletions
  1. 26 3
      src/load-service.cc

+ 26 - 3
src/load-service.cc

@@ -334,7 +334,18 @@ service_record * dirload_service_set::load_reload_service(const char *name, serv
             };
 
             auto load_service_n = [&](const string &dep_name) -> service_record * {
-                return load_service(dep_name.c_str(), reload_svc);
+                try {
+                    return load_service(dep_name.c_str(), reload_svc);
+                }
+                catch (service_description_exc &sle) {
+                    log_service_load_failure(sle);
+                    throw service_load_exc(name, "could not load dependency.");
+                }
+                catch (service_load_exc &sle) {
+                    log(loglevel_t::ERROR, "Could not load service ", sle.service_name, ": ",
+                            sle.exc_description);
+                    throw service_load_exc(name, "could not load dependency.");
+                }
             };
 
             process_service_line(settings, name, line, line_num, setting, i, end, load_service_n,
@@ -423,7 +434,19 @@ service_record * dirload_service_set::load_reload_service(const char *name, serv
         std::list<service_dep> before_deps;
         if (dummy == nullptr) {
             for (const std::string &before_ent : settings.before_svcs) {
-                service_record *before_svc = load_service(before_ent.c_str());
+                service_record *before_svc;
+                try {
+                    before_svc = load_service(before_ent.c_str());
+                }
+                catch (service_description_exc &sle) {
+                    log_service_load_failure(sle);
+                    throw service_load_exc(name, "could not load dependency.");
+                }
+                catch (service_load_exc &sle) {
+                    log(loglevel_t::ERROR, "Could not load service ", sle.service_name, ": ",
+                            sle.exc_description);
+                    throw service_load_exc(name, "could not load dependency.");
+                }
                 before_deps.emplace_back(before_svc, reload_svc, dependency_type::BEFORE);
                 // (note, we may need to adjust the to-service if we create a new service record object)
                 check_cycle(settings.depends, before_svc);
@@ -684,7 +707,7 @@ service_record * dirload_service_set::load_reload_service(const char *name, serv
         if (create_new_record) delete rval;
         throw service_load_exc(name, sys_err.what());
     }
-    catch (...) // (should only be std::bad_alloc)
+    catch (...) // (should only be std::bad_alloc or service_load_exc)
     {
         if (dummy != nullptr) {
             records.erase(std::find(records.begin(), records.end(), dummy));