Skip to content

Support optional Sentry integration for error tracking #24

@StephanMeijer

Description

@StephanMeijer

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:

  1. Add sentry as a regular dependency in mix.exs:

    {:sentry, "~> 10.0"}
  2. 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
  3. Sentry is configured via environment variables:

    • DOCSPEC_SENTRY_DSN — Sentry DSN. When unset or empty, all error reporting is no-op.
  4. 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:

  1. Report the error to Sentry (via DocSpec.ErrorReporter) — for debugging
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions