BlameThrower

Identifies which addon actually caused each Lua error. Walks the stack, skips libraries and blames the real culprit — with severity, grouping, and ignores.

File Details

v0.1.0

  • R
  • Apr 23, 2026
  • 30.30 KB
  • 4
  • 12.0.5
  • Retail

File Name

BlameThrower-v0.1.0.zip

Supported Versions

  • 12.0.5

BlameThrower

v0.1.0 (2026-04-23)

Full Changelog Previous Releases

  • Set CurseForge project ID to 1523049
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Use Spell_Fire_Incinerate icon for addon and minimap button
    Replaces the placeholder rifle icon with a fire-beam spell icon
    that reads as "flamethrower" — visible in the addon list and on
    the minimap button.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Scaffold CurseForge release via BigWigs Packager
    GitHub Action triggers on v* tags, builds the addon, and uploads to
    CurseForge using CF_API_KEY. Vendored libs are kept as-is; .pkgmeta
    just names the package and drops .claude + Test.lua from the zip.
    Test.lua's TOC reference is wrapped in #@debug@ so the packager
    strips it from release builds — it auto-injects fake errors on
    login and must not ship.
    X-Curse-Project-ID is a placeholder (000000) pending actual project
    creation on CurseForge.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Replace Clear button with trashcan + confirm dialog
    Right-aligned trashcan in the topbar opens a small dialog with two
    actions: Clear All Data (wipes everything including BugGrabber's DB)
    and Clear Old Data (keeps only current-session entries, including
    older-session entries in the persisted fallback list). Cancel and
    the X close the dialog without touching state; ESC does the same.
    The clear logic moved to ns:ClearAll(alsoWipeBugGrabber) and
    ns:ClearOldSessions() in Core so the slash handler and the dialog
    share it. /blame clear and /blame clear all keep their existing
    semantics; added /blame clear old for symmetry with the dialog.
    Trashcan uses the communities-icon-trashcan atlas on retail with a
    UI-GroupLoot-Pass fallback if the atlas isn't present.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Consolidate severity + mute helpers; expand .gitignore
    Severity became one SEV table in Core (rank/rgb/hex per tier),
    replacing three scattered copies: Core's SEV_RGB + SEV_RANK,
    Broker's local COLOR, and Broker's sevRGB() helper. The tooltip
    keeps its slightly darker gray via a single-line override rather
    than a second RGB table.
    Added ns:VisibleUnseenCount() and ns:SortCulprits(stats, mode),
    collapsing four ad-hoc "count unseen visible entries" loops and the
    duplicated severity-ranked sort comparator that lived in both
    Broker.sortedCulprits and Frame.rebuildErrorsView.comparators.
    Mute-table init moved into ADDON_LOADED alongside fallbackErrors,
    which let the per-call ensureMuteTables() pattern go away entirely.
    Dropped the dead ns:Toggle in Core (Frame.lua's overrides it
    on load). Frame's three-block mute context menu collapses to a
    MUTE_TIERS loop.
    .gitignore: added Thumbs.db, more editor swaps/backups, luac
    output, and packager artifacts (.release/, *.zip).
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Fix main frame rendering empty when errors exist
    FILTER_LABELS was declared as local below applyViewChrome, so the
    reference at line 597 resolved to the nil global — every rebuild()
    threw "attempt to index a nil value" and the frame appeared empty
    even when VisibleEntries had results. Move the label/order constants
    above the first function that uses them.
    Broker text, tooltip, and icon color previously mixed raw entry
    counts (#ns.entries, ns.unseenCount) with the frame's filtered view
    (VisibleEntries). When the frame was also broken, the disagreement
    was visible: icon red, tooltip populated, frame blank. Drive all
    three surfaces from VisibleEntries so they stay consistent with
    what the user sees.
    /blame debug now prints visible/unseen counts, per-session entry
    histogram, and the first unattributed error's stack — enough to
    distinguish "filter hiding entries" from "rebuild crashing" next
    time something goes sideways.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Add mute system, sort/filter dropdowns, restructured frame UI
    Mutes (three-tier):
    • Ignore: dropped at ingest, never recorded. Persistent in SavedVariables.
    • Snooze forever: recorded but silent (no pulse, hidden from view). Persistent.
    • Snooze for session: same, but in-memory only, clears on /reload.
      Right-click an error row for a MenuUtil checkbox menu that toggles the
      current tier. Applying any tier clears the others (promotion).
      Frame restructure:
    • Topbar (title + Clear), content panel (own border, tabs attached to its
      top edge), and status bar at bottom. Controls moved from scattered
      bottom-row placement to a proper top toolbar.
    • Errors/Ignored tabs replace the standalone mutes modal. Active tab uses
      a red highlight; inactive is dim gray.
    • Errors view tools: Filter dropdown + Sort dropdown. Ignored view tools:
      Unmute All. Tools swap with the active tab.
    • Sort options: Severity, Count, Time, Name.
    • Filter options: Session (default), All.
    • Bottom status line reduced to "N errors" / "N ignored".
    • ESC closes via UISpecialFrames (standard convention).
    • All dropdowns migrated from EasyMenu (removed in 11.0) to
      MenuUtil.CreateContextMenu.
      Opacity and borders:
    • Unified 0.92 alpha across main frame, topbar, content panel, and copy
      dialog so the whole window reads as consistently semi-opaque. Earlier
      attempt at stacked opacity produced a jarring "transparent outer,
      opaque inner" look because child frames cover their parent.
    • Black 1px borders. Backdrops use solid color textures rather than the
      older tiled dark-dialog background.
    • ElvUI skin hook intentionally only handles buttons, close, and
      scrollbar — not the frames themselves, since HandleFrame overrides
      backdrop alpha with ElvUI's own theme value and breaks the chosen
      opacity.
      Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Polish main frame: real icons, bigger sizing, ElvUI skin hook
    • Replace unicode arrows/dots (▸ ▾ ● ○) with Blizzard texture atlas
      paths (UI-PlusButton-Up, UI-MinusButton-Up, COMMON/Indicator-Green,
      COMMON/Indicator-Gray) so rows render the same regardless of font.
    • Bump frame to 720x560, group rows to 38px with GameFontNormalMed1
      for the addon name, error rows to 28px, and add row-hover highlight
      textures. More breathing room between groups.
    • Explicit SetWidth on the detail-row stack FontString so
      GetStringHeight returns a real value on first expand instead of 0.
    • Detect _G.ElvUI and call its public Skins API (HandleFrame,
      HandleButton, HandleCloseButton, HandleScrollBar) so ElvUI users
      get the sleek reskin automatically. No-op without ElvUI.
      Initial attempt used BasicFrameTemplateWithInset, but main.TitleText
      and main.Inset did not resolve as Lua attributes on 12.0.5, erroring
      createFrame mid-way and leaving a blank window. Reverted to a custom
      BackdropTemplate (reliable) and routed skinning through the explicit
      ElvUI hook instead.
      Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Strip executable bit from all tracked files
    NTFS-via-WSL reported every file as 100755. Files are plain text, not
    scripts. Set core.fileMode=false in the repo config (local-only) so
    future mode noise is ignored, and normalize the index to 100644.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • Initial commit: BlameThrower v0.1.0
    A WoW addon that attributes Lua errors to the responsible addon by
    parsing stack traces, with library-aware root-cause detection that
    sees through shared infrastructure (Ace3, LibStub, CallbackHandler) to
    blame the application caller rather than the framework it called.
    • Consumes BugGrabber 12.x via EventRegistry; falls back to a chained
      seterrorhandler when BugGrabber isn't loaded.
    • Three entry points: /blame slash command, LDB broker, LibDBIcon
      minimap button with severity tint and one-time soft pulse.
    • Main frame: culprit groups sorted by unseen/severity/count, each
      expandable to unique errors, each expandable to a detail panel with
      stripped Blizzard stack, copy dialog, and disable-addon action.
    • Session filter (default: current session only) so past-session
      errors from BugGrabber's DB don't drown the view.
    • Test.lua ships six synthetic fixtures covering high/medium/low
      confidence, Via: chains, and unattributable Blizzard-only errors
      for design-time validation. Auto-injects on load; toggle via
      /blame autotest off.
    • Embeds LibStub, CallbackHandler-1.0, LibDataBroker-1.1, LibDBIcon-1.0
      so the addon is self-contained.
      Targets WoW 12.0.5 (Midnight); TOC interface 120005.
      Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com