Summary
Add optional Sentry support to DocSpec so that errors during document conversion can be reported to Sentry when enabled via environment variable at runtime.
Motivation
Document conversion can fail in subtle ways — malformed DOCX internals, unexpected XML structures, encoding issues, etc. When used as a library in production services (e.g. docspecio/api), having automatic error reporting to Sentry helps identify and fix issues in the wild that test suites cannot cover.
Sentry must be off by default and enabled only when explicitly configured.
Proposal
Approach: Runtime toggle via environment variable
Since DocSpec ships as a Burrito native binary, all dependencies are compiled into the release. Compile-time optional: true doesn't help — the binary includes Sentry either way. Instead, the toggle is purely runtime:
-
Add sentry as a regular dependency in mix.exs:
-
Create a wrapper module gated by an env var:
defmodule DocSpec.ErrorReporter do
@moduledoc "Reports errors to Sentry when enabled, no-ops otherwise."
def capture_exception(exception, opts \\ []) do
if enabled?() do
Sentry.capture_exception(exception, opts)
else
:ok
end
end
def capture_message(message, opts \\ []) do
if enabled?() do
Sentry.capture_message(message, opts)
else
:ok
end
end
defp enabled? do
# Truthy when DOCSPEC_SENTRY_DSN is set to a non-empty value
case System.get_env("DOCSPEC_SENTRY_DSN") do
nil -> false
"" -> false
_dsn -> true
end
end
end
-
Sentry is configured via environment variables:
DOCSPEC_SENTRY_DSN — Sentry DSN. When unset or empty, all error reporting is no-op.
-
Instrument key error paths:
DOCX.Reader.open!/1 — file extraction failures
DOCX.Reader.convert!/1 — conversion errors
- Writer modules — when they return
{:error, reason}
- CLI error handler — unhandled exceptions
What this does NOT do
- Does not enable Sentry by default — requires explicit env var
- Does not change any return types or public API
- Does not add runtime overhead when disabled — early return on
enabled?() check
- Does not block conversion on reporting failures — fire-and-forget
Co-existence with PostHog (#25)
Both Sentry and PostHog must work independently and together. A consumer should be able to enable either, both, or neither. The two modules (DocSpec.ErrorReporter for Sentry, DocSpec.Analytics for PostHog) are intentionally separate — they serve different purposes (error tracking vs product analytics), have non-overlapping interfaces, and each checks its own env var at runtime. No shared abstraction needed; keeping them independent ensures enabling one never affects the other.
When both are active, a failed conversion would:
- Report the error to Sentry (via
DocSpec.ErrorReporter) — for debugging
- Emit a
conversion_failed event to PostHog (via DocSpec.Analytics) — for trend tracking
These happen independently with no coupling between them.
Usage
# Error reporting disabled (default)
docspec convert -i doc.docx -o out.html
# Error reporting enabled
DOCSPEC_SENTRY_DSN=https://abc123@o123.ingest.sentry.io/456 docspec convert -i doc.docx -o out.html
# Both Sentry and PostHog enabled
DOCSPEC_SENTRY_DSN=https://abc123@o123.ingest.sentry.io/456 \
DOCSPEC_POSTHOG_KEY=phc_abc123 \
docspec convert -i doc.docx -o out.html
Alternatives considered
- Compile-time
optional: true: Doesn't work with Burrito — the binary ships with all deps baked in regardless
- Behaviour-based error reporter: Over-engineered for a single integration
- Telemetry events only: Good complement but doesn't provide the error context Sentry captures (stacktraces, breadcrumbs)
- Leave to consumers: Current state — works but means every consumer re-implements the same instrumentation
Related
Files to modify
mix.exs (add dep)
- New:
lib/docspec/error_reporter.ex
lib/docspec/core/docx/reader.ex (instrument error paths)
- Writer modules as appropriate
Summary
Add optional Sentry support to DocSpec so that errors during document conversion can be reported to Sentry when enabled via environment variable at runtime.
Motivation
Document conversion can fail in subtle ways — malformed DOCX internals, unexpected XML structures, encoding issues, etc. When used as a library in production services (e.g.
docspecio/api), having automatic error reporting to Sentry helps identify and fix issues in the wild that test suites cannot cover.Sentry must be off by default and enabled only when explicitly configured.
Proposal
Approach: Runtime toggle via environment variable
Since DocSpec ships as a Burrito native binary, all dependencies are compiled into the release. Compile-time
optional: truedoesn't help — the binary includes Sentry either way. Instead, the toggle is purely runtime:Add
sentryas a regular dependency inmix.exs:Create a wrapper module gated by an env var:
Sentry is configured via environment variables:
DOCSPEC_SENTRY_DSN— Sentry DSN. When unset or empty, all error reporting is no-op.Instrument key error paths:
DOCX.Reader.open!/1— file extraction failuresDOCX.Reader.convert!/1— conversion errors{:error, reason}What this does NOT do
enabled?()checkCo-existence with PostHog (#25)
Both Sentry and PostHog must work independently and together. A consumer should be able to enable either, both, or neither. The two modules (
DocSpec.ErrorReporterfor Sentry,DocSpec.Analyticsfor PostHog) are intentionally separate — they serve different purposes (error tracking vs product analytics), have non-overlapping interfaces, and each checks its own env var at runtime. No shared abstraction needed; keeping them independent ensures enabling one never affects the other.When both are active, a failed conversion would:
DocSpec.ErrorReporter) — for debuggingconversion_failedevent to PostHog (viaDocSpec.Analytics) — for trend trackingThese happen independently with no coupling between them.
Usage
Alternatives considered
optional: true: Doesn't work with Burrito — the binary ships with all deps baked in regardlessRelated
Files to modify
mix.exs(add dep)lib/docspec/error_reporter.exlib/docspec/core/docx/reader.ex(instrument error paths)