sj26/mailcatcher · info
Backtrace:
Error message
Backtrace:
What it means
The backtrace section of log_exception (lib/mail_catcher.rb:63). Each frame of exception.backtrace is printed with gem installation directories rewritten by the regex on line 58 into `gemname (version) relative/path`, so frames read like `mail (2.7.1) lib/mail/message.rb:123` instead of absolute gem paths. It is printed with puts as the label followed by the mapped lines.
Source
Thrown at lib/mail_catcher.rb:63
windows? or which? "open"
end
def browse url
if windows?
system "start", "/b", url
elsif which? "open"
system "open", url
end
end
def log_exception(message, context, exception)
gems_paths = (Gem.path | [Gem.default_dir]).map { |path| Regexp.escape(path) }
gems_regexp = %r{(?:#{gems_paths.join("|")})/gems/([^/]+)-([\w.]+)/(.*)}
gems_replace = '\1 (\2) \3'
puts "*** #{message}: #{context.inspect}"
puts " Exception: #{exception}"
puts " Backtrace:", *exception.backtrace.map { |line| " #{line.sub(gems_regexp, gems_replace)}" }
puts " Please submit this as an issue at https://github.com/sj26/mailcatcher/issues"
end
@@defaults = {
:smtp_ip => "127.0.0.1",
:smtp_port => "1025",
:http_ip => "127.0.0.1",
:http_port => "1080",
:http_path => "/",
:messages_limit => nil,
:verbose => false,
:daemon => !windows?,
:browse => false,
:quit => true,
}
def options
@@optionsView on GitHub (pinned to 18a9cb7a79)
Solutions
- Read the deepest non-gem frame first — it names the code at fault (e.g. `sqlite3 (1.4.x)` frames point at the DB layer, `mail (...)` frames at MIME parsing).
- Reproduce with `mailcatcher --foreground --verbose` to get the trace directly in your terminal.
- Pin the guilty gem back to the last working version (common outcome: sqlite3, mail) and restart.
- If frames point into mailcatcher's own lib/, file the issue with this trace attached.
Defensive patterns
Strategy: fallback
Try / catch
# Capture the full report (context + exception + rewritten backtrace) yourself when embedding
begin
MailCatcher::Mail.add_message(msg)
rescue => e
File.write("mailcatcher-crash.log", [e.message, *e.backtrace].join("\n"))
raise unless e.is_a?(SQLite3::Exception) # re-raise what you cannot handle
end Prevention
- Keep daemon logs rotated and retained so rewritten gem traces survive for triage.
- Before upgrading Ruby or the mail/mailcatcher gems, note versions; the rewritten frames let you diff which gem moved.
- Reproduce crashes with --foreground so the trace lands in a terminal you can copy.
When it happens
Trigger: Printed automatically on the same conditions as the `***` header: any exception caught by rescue in MailCatcher::Smtp#receive_message (smtp.rb:62) or in the websocket send callback (application.rb:89). The rewriting itself can raise ArgumentError if Gem.path/Gem.default_dir contain regex-metacharacter characters, but in practice it always renders the cleaned trace.
Common situations: Needing to know whether the fault is inside mailcatcher, the sqlite3 gem, the mail gem, or faye-websocket when only a one-line symptom is visible; debugging in daemon mode where the report scrolls away; comparing traces across gem versions after a bundle update changed behavior.
Related errors
- *** #{message}: #{context.inspect}
- Exception: #{exception}
- Please submit this as an issue at https://github.com/sj2
AI-assisted analysis of sj26/mailcatcher@18a9cb7a79 (2026-08-21).
Data as JSON: /api/errors/24c27d5332b463c0.
Report an issue: GitHub.