← Blog

Built-In Bug Reporting: How We Built a Universal Error Reporting System

Discover how Reliable Communications built a universal bug reporting system for AvatarMatch, enhancing user experience and error tracking.

Built-In Bug Reporting: How We Built a Universal Error Reporting System

Every product eventually faces the same problem: users find bugs but don’t know how to report them. An email to support@? A screenshot in a messenger? A social media post? The harder the path from discovering a problem to fixing it, the more bugs go unreported.

At Reliable Communications s.r.o., we solved this problem systematically — and built an embedded bug reporting platform that works directly inside the application. It’s already running in production at AvatarMatch, but it’s designed as a universal module suitable for any web product.

In this article, we’ll take a detailed look at the architecture, the processing pipeline, and the capabilities of the system.

The Problem: Why External Trackers Don’t Work for End Users

Jira, Linear, GitHub Issues — all great tools for development teams. But try asking an ordinary user to create an issue in GitHub. The result is predictable: 95% of bugs simply won’t get reported.

The classic “email us” approach is equally flawed:

  • The user won’t specify the URL where the error occurred
  • Won’t include the browser version and OS
  • Won’t describe reproduction steps
  • Support will spend time on follow-up questions
  • The bug will get lost in an email thread

What you need is a tool that’s embedded in the product, collects context automatically, and gives the user a simple, clear form.

System Architecture

Components

The system consists of several layers:

Layer Technology Purpose Floating Action Button (FAB) React + Lucide Icons Entry point — visible on every page Drawer with form React Collects description, expected behavior, steps, attachments Attachment uploader React + Firebase Storage Images (PNG, JPEG, WebP) and videos (MP4, WebM) Auto-context collection Client-side JS URL, browser, OS, device, viewport, locale, timezone, app version REST API Astro SSR endpoints Creation, listing, filtering, moderation Storage Firestore Bug documents, timeline events, counters Bug portal Astro + React View all/my reports, detailed report card AI triage Server pipeline Automatic validation, normalization, classification GitHub integration Admin API Link to issues, status sync Analytics Custom Events Tracking user actions throughout the funnel

The Floating Button — Entry Point

On every page of the application (except authentication pages: /login, /register, /forgot-password, /auth/*, /wizard), a floating button with a bug icon is displayed. The exclusion list is configurable via the PUBLIC_BUG_REPORT_EXCLUDE_PREFIXES environment variable.

Clicking it opens a Drawer — a side panel with the report form. If the user isn’t authenticated, they’ll see a login prompt. If the form has been filled in and the user tries to close the drawer, the system shows a discard confirmation.

The Report Form

The form contains the following fields:

  1. Title (optional, up to 120 characters) — a brief description of the problem
  2. What happened (required, 10–5,000 characters) — a detailed bug description
  3. Expected behavior (required, 5–3,000 characters) — what should have happened
  4. Steps to reproduce (optional, up to 3,000 characters) — step-by-step instructions
  5. Visibility — private or public report
  6. Attachments — up to 5 files: images up to 10 MB, videos up to 100 MB (up to 90 seconds long)

Validation happens both client-side (instant hints) and server-side (re-checking all constraints).

Automatic Context Collection

One of the system’s key features is automatic technical context collection at the moment of report submission. The user doesn’t need to know anything about their browser — the system detects everything automatically:

  • Page URL and route name
  • Page title
  • Browser and version (Chrome, Safari, Firefox, Edge)
  • Operating system (Windows, macOS, Android, iOS, Linux)
  • Device type (desktop, mobile, tablet)
  • Viewport and screen resolution
  • Locale and timezone
  • App version
  • Session ID (generated client-side, stored in sessionStorage)

This context is sent to the server along with the form and saved in the bug document. When viewing the report in the portal, a developer sees the complete picture of the environment where the error occurred.

Bug Lifecycle: From PendingCheck to Resolved

Every bug report goes through a formalized status pipeline:

PendingCheck → Normalizing → Triaging → RepoChecking → Confirmed → InProcess → Open → Resolved
↘ Closed
↗ Cancelled
↗ Duplicate
↗ Rejected

Status Breakdown

Status Meaning PendingCheck Report just created, awaiting initial review Normalizing AI normalizes text: fixes formatting, extracts structure Triaging AI determines priority, category, and potential impact level RepoChecking Checking for duplicates among existing reports Confirmed Bug confirmed, awaiting assignment InProcess Fix is being worked on Open Bug is open and registered in the tracker Resolved Fix has been completed Closed Report closed (manually or automatically) Cancelled Cancelled by author or moderator Duplicate Marked as a duplicate of an existing report Rejected Declined (not a bug, unreproducible, out of scope)

Terminal statuses — Cancelled, Closed, Duplicate, Rejected, Resolved — block further content editing and cancellation of public reports by the author.

AI Triage: Automatic Report Processing

After creation, a report passes through a server-side AI pipeline that performs several steps:

  1. Normalization — structuring text, fixing obvious typos, extracting key data
  2. Triage — automatic determination of severity (impact level), category, and priority
  3. Duplicate detection — comparison with existing open reports
  4. Validation — filtering out spam, invalid, or empty reports

Each step logs token usage (prompt, completion, total), enabling monitoring of AI processing costs. Token usage data is visible to administrators in the report detail view — with per-step breakdowns.

Visibility and Privacy

Share this article

← All posts

Loading comments…