Health alerts
Every uncached request to Entra ID or Dataverse reports its outcome to a small health monitor. The first failure of an episode sends an email right away, repeats are held back by a cooldown, and the first success afterwards sends a recovery notice. A scheduled probe twice a day catches problems that would otherwise wait for a visitor, above all an expired client secret.
What triggers an alert
Failures are grouped into four classes. Each class has its own explanation in the email.
| Class | Recorded when | Typical cause |
|---|---|---|
| auth | The token endpoint rejects the request | Expired or rotated client secret, wrong client or tenant id, deleted app registration |
| network | The token endpoint or the environment URL is unreachable | DNS or firewall on the host, a Microsoft outage, a mistyped environment URL |
| api | A read returns 401, 403, 408, 429 or any 5xx | Application user without a role, revoked privileges, throttling, a Dataverse incident |
| form | A form write fails, whatever the status code | Missing Create or Write privilege, a required column the form does not fill, a wrong entity set |
A 404 while browsing is a content matter, not an outage, and does not count. Metadata reads never touch the health state either: they are optional and fall back to heuristics, so a failing metadata endpoint next to working data reads cannot raise and clear alerts in turn.
An email goes out on the first failure of an episode, again when the failure class changes (a network problem turning into an auth problem, for example), and again after the cooldown while the episode lasts. Failed form submissions always count as alert-worthy because a visitor lost a submission.
Cooldown
Repeat alerts for one ongoing episode are held back for six hours. Change it with the wbs_dataverse_connect_alert_cooldown filter, which receives and returns seconds:
add_filter('wbs_dataverse_connect_alert_cooldown', function () {
return 2 * HOUR_IN_SECONDS;
});
Recovery
The first successful request after a failure episode resets the state and sends a recovery email with the time the episode started and the last recorded error. Only episodes that were announced get a recovery notice, so a single hiccup below the alert threshold stays quiet in both directions.
The scheduled probe
A WP-Cron event runs twice a day (the first run one hour after activation). It drops the cached token, requests a fresh one with the stored credentials and calls WhoAmI. The outcome flows through the same reporting as visitor-driven requests, so a broken connection alerts within hours even when nobody is on the site. This is the answer to the classic silent failure: a client secret that expired on a quiet site and surfaced weeks later as a form that "does not work". The probe needs WP-Cron to run; on hosts that disable it, trigger wp-cron.php from a system cron.
The Connection tab shows the current state (OK or Failing since when, with the last error) and the time of the last probe. Test connection on the same tab runs the same roundtrip on demand.
Recipients and settings
Under Health alerts on the Connection tab:
- Send alerts: on by default.
- Alert email: empty means the site admin email.
- Also alert: a second address, for example the partner who maintains the integration.
The wbs_dataverse_connect_alert_recipients filter changes the list for anything beyond that. Mail goes through wp_mail, so whatever SMTP plugin the site uses applies. The subject reads [Site name] Dataverse connection problem or [Site name] Dataverse connection restored.
The health_event action
wbs_dataverse_connect_health_event fires on every recorded failure (alerted or not) and on every recovery, with the kind and the stored state:
add_action('wbs_dataverse_connect_health_event', function ($kind, $state) {
// $kind: 'failure' or 'recovery'
// $state: state, class, detail, context, since, last_seen, alerted_at, checked_at
if ($kind === 'failure' && $state['class'] === 'auth') {
// open a ticket, page someone, ...
}
}, 10, 2);
The webhook module listens to this action and turns alerted failures into health.failure messages and recoveries into health.recovery; see Webhooks. The state is stored in the wbsdvc_health option and removed on uninstall.