Adaptation::Service::finalize();
theService = FindAdapterService(cfg().uri);
if (theService) {
- debugs(93,2, HERE << "configuring eCAP service: " << theService->uri());
- const ConfigRep cfgRep(dynamic_cast<const ServiceConfig&>(cfg()));
- theService->configure(cfgRep);
-
- debugs(93,DBG_IMPORTANT, "Starting eCAP service: " << theService->uri());
- theService->start();
+ try {
+ tryConfigureAndStart();
+ Must(up());
+ }
+ catch (const std::exception &e) { // standardized exceptions
+ if (!handleFinalizeFailure(e.what()))
+ throw; // rethrow for upper layers to handle
+ }
+ catch (...) { // all other exceptions
+ if (!handleFinalizeFailure("unrecognized exception"))
+ throw; // rethrow for upper layers to handle
+ }
+ return; // success or handled exception
} else {
debugs(93,DBG_IMPORTANT, "WARNING: configured ecap_service was not loaded: " << cfg().uri);
}
}
+/// attempts to configure and start eCAP service; the caller handles exceptions
+void
+Adaptation::Ecap::ServiceRep::tryConfigureAndStart()
+{
+ debugs(93,2, HERE << "configuring eCAP service: " << theService->uri());
+ const ConfigRep cfgRep(dynamic_cast<const ServiceConfig&>(cfg()));
+ theService->configure(cfgRep);
+
+ debugs(93,DBG_IMPORTANT, "Starting eCAP service: " << theService->uri());
+ theService->start();
+}
+
+/// handles failures while configuring or starting an eCAP service;
+/// returns false if the error must be propagated to higher levels
+bool
+Adaptation::Ecap::ServiceRep::handleFinalizeFailure(const char *error)
+{
+ const bool salvage = cfg().bypass;
+ const int level = salvage ? DBG_IMPORTANT : DBG_CRITICAL;
+ const char *kind = salvage ? "optional" : "essential";
+ debugs(93, level, "ERROR: failed to start " << kind << " eCAP service: " <<
+ cfg().uri << ":\n" << error);
+
+ if (!salvage)
+ return false; // we cannot handle the problem; the caller may escalate
+
+ // make up() false, preventing new adaptation requests and enabling bypass
+ theService.reset();
+ debugs(93, level, "WARNING: " << kind << " eCAP service is " <<
+ "down after initialization failure: " << cfg().uri);
+
+ return true; // tell the caller to ignore the problem because we handled it
+}
+
bool Adaptation::Ecap::ServiceRep::probed() const
{
return true; // we "probe" the adapter in finalize().