Skip to content

Errors and logging

Erik Hennerfors edited this page Oct 13, 2026 · 3 revisions

What happens when a call fails, and how to see it.

Telemetry and management handle failures differently: telemetry never breaks the job it monitors, so it returns false; management calls throw, since you can't continue without their result.

Telemetry

Telemetry events (Telemetry) never throw because Cronitor can't be reached:

  • Transient failures (network errors, timeouts, and 408, 429 and 5xx responses) are retried three times, after about 2, 4 and 8 seconds. Each attempt times out after 10 seconds, and an event gives up after 30 seconds in total.
  • If an event still can't be delivered, the method returns false, and the failure is logged. A delivered event returns true.
var delivered = await CronitorClient.CompleteAsync("monitorKey");
if (!delivered)
{
    // the job succeeded, but Cronitor doesn't know yet
}

In a using block, Complete and Fail return false in the same way, and also when the run was already completed or failed. Disposing a run never throws.

Management

Monitors, Activity, Issues and Notifications calls are sent once, without retries, and throw when they fail:

Exception When
ApiException (Cronitor.Exceptions) Cronitor answered with an error, such as 404 for a monitor that doesn't exist or 400 for an invalid request. The message is Cronitor's description of the error, followed by the status code in parentheses, e.g. (NotFound).
HttpRequestException Cronitor couldn't be reached.
TaskCanceledException Cronitor didn't answer within 100 seconds.
using Cronitor;
using Cronitor.Exceptions;

try
{
    await CronitorClient.Monitors.PauseAsync("monitorKey", hours: 2);
}
catch (ApiException ex)
{
    Console.WriteLine($"Cronitor refused the request: {ex.Message}");
}

Management calls aren't logged; handle or log the exceptions yourself.

Configuration errors

Mistakes in your own code throw, for telemetry too:

Exception When
NotConfiguredException (Cronitor.Exceptions) The static CronitorClient is used before Configure or .UseCronitor(), see Setup.
ArgumentNullException An empty or whitespace monitor key, API key, or With… value on a custom command.

Logging

Telemetry events that can't be delivered, even after retries, are logged as errors through ILogger (Microsoft.Extensions.Logging). With the console logger, an entry starts like this, followed by the exception:

fail: Cronitor.TelemetriesClient[1]
      Could not deliver run event for monitor nightly-backup to Cronitor

The entry never contains the telemetry URL, since that contains your API key.

With the .NET Generic Host, both .ConfigureCronitor() and .UseCronitor() use the host's logging automatically, so there is nothing to set up. For .UseCronitor(), logging applies from when the host starts.

Without a host, pass an ILoggerFactory, either to the static CronitorClient or to a client:

using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());

CronitorClient.Configure("apiKey", loggerFactory);
// or
var telemetriesClient = new TelemetriesClient("apiKey", loggerFactory);

AddConsole() comes from the Microsoft.Extensions.Logging.Console package; any logging provider works. Without an ILoggerFactory, nothing is logged.

Clone this wiki locally