Problem/Motivation
config/install/subscription_manager.settings.yml ships only site_id, api_key, log_webhooks, and manage_route. The default_connector key (and redirect, custom_subscribe_url) exists only in the schema, so on a fresh install it is NULL until an admin saves the settings form. SubscriptionManagerController::subscribe() and getSubscribeUrl() pass the value straight to createInstance(); the hasDefinition() fallback falls back to the same NULL. Result: an uncaught plugin exception (500) on /subscription-manager/subscribe for any newly installed site that hasn't visited the settings form. _subscription_manager_sync_remote_subscriptions() already guards empty($connector_id); the controller paths don't.
Steps to reproduce
- Fresh install of subscription_manager plus one connector module; do not save the admin form.
- As a user with
manage own subscriptions, visit /subscription-manager/subscribe: fatal.
Proposed resolution
- Guard both controller paths: when the resolved connector ID is empty or has no definition, log, show a friendly message, and redirect (front page for members; settings form link for admins).
getSubscribeUrl()returns an error shape instead of throwing. - Reduce the window: when exactly one connector plugin is installed and
default_connectoris unset, treat that connector as the default (and/or set it on connector-module install). - Add
#requiredto the admin form's connector select, and add the missing keys with sensible defaults to config/install so config schema and install state agree.
Remaining tasks
Patch; kernel test for the unconfigured path; verify the single-connector auto-default against #3616769: Add a connector chooser to the subscribe flow when multiple connectors provide plans's chooser logic (they compose: chooser only engages when multiple connectors have plans).
User interface changes
Friendly error instead of a 500; required select on the settings form.
API changes
getSubscribeUrl gains a documented error response shape.
Data model changes
None (config/install defaults only).
Issue fork subscription_manager-3616932
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
colanComment #4
colanMR opened, implementing all three parts of the proposed resolution:
SubscriptionManagerService::getDefaultConnector()now validates the configured value and, when it is unset or references a missing plugin, infers the single installed connector as the default — so every caller (controller paths and the self-healing sync) benefits. With several connectors and no configured default it returns NULL rather than guessing. Verified against #3616769: Add a connector chooser to the subscribe flow when multiple connectors provide plans's chooser logic: they compose, since the chooser only engages when multiple connectors provide plans.resolveConnector()helper now feeds everycreateInstance()call site (the two portal paths had the same hole when a subscription's stored connector is missing and no default resolves, so they are guarded too). Page routes redirect with a friendly message — admins to the settings form, members to the front page;getSubscribeUrl()andgetPortalUrl()return a documented 503 shape (error: no_connector_available) instead of throwing.config/installgains thedefault_connector,redirect, andcustom_subscribe_urlkeys the schema already declared, and the settings form's connector select is now#requiredwith an empty option.DefaultConnectorGuardTestcovers the unconfigured page path (member and admin redirects), the API error shape, the single-connector auto-default, and that multiple connectors infer nothing while a configured default wins. The auto-default needed a newsubscription_manager_solo_testmodule providing exactly one connector, sincesubscription_manager_testships two.Comment #6
colan