sj26/mailcatcher · error
*** #{message}: #{context.inspect}
Error message
*** #{message}: #{context.inspect} What it means
This is the header line of MailCatcher's catch-all crash reporter, log_exception (lib/mail_catcher.rb:56-65). It is not raised; it is printed when an internal `rescue => exception` in SMTP message handling (smtp.rb:62) or the websocket bus push (application.rb:89) catches an unexpected exception and logs `*** <message>: <context.inspect>`. The context is the @current_message hash (sender/recipients/source) or the bus message that was being processed when the failure occurred.
Source
Thrown at lib/mail_catcher.rb:61
def browsable?
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,
}
View on GitHub (pinned to 18a9cb7a79)
Solutions
- Read the next two lines of the same report (`Exception:` and `Backtrace:`) — they name the real error class and the failing gem frame; fix that first.
- Run in the foreground with verbosity so output is not lost to daemonization: `mailcatcher --foreground --verbose`.
- If the Exception line mentions SQLite3/null bytes or argument errors, align gem versions: `gem uninstall sqlite3; gem install sqlite3 -v 1.3.13` (or upgrade the mailcatcher gem to the latest release, which pins a compatible sqlite3).
- Reproduce with a minimal email (plain text, ASCII headers) to confirm whether malformed MIME content is the trigger; if it is, fix or normalize what the sending app delivers.
- If the backtrace shows a genuine MailCatcher bug, follow the printed advice and file it at https://github.com/sj26/mailcatcher/issues with the full block.
Example fix
# before: exception inside add_message surfaces only as
# *** Error receiving message: {:sender=>"app@example.com", ...}
# after: capture the full report when triaging
mailcatcher --foreground --verbose 2>&1 | tee mailcatcher.log
# then align the known-incompatible gem
# Gemfile: gem "sqlite3", "~> 1.3.6" -> bundle update sqlite3 mailcatcher Defensive patterns
Strategy: try-catch
Try / catch
# The library already rescues; the guard a caller/embedder needs is around its own hooks.
# If you drive MailCatcher as a library and reuse MailCatcher::Mail:
begin
MailCatcher::Mail.add_message(sender: "app@example.com", recipients: ["to@example.com"], source: raw_rfc2822)
rescue => e
warn "persistence failed for #{raw_rfc2822.bytesize} bytes: #{e.class}: #{e.message}"
# keep the raw mail on disk so it is not lost when the report fires
File.binwrite("failed/#{Time.now.to_i}.eml", raw_rfc2822)
end Prevention
- Run `mailcatcher --foreground --verbose` whenever you change gems so reports are seen, not swallowed by daemon mode.
- Pin or jointly upgrade mailcatcher + sqlite3 + mail; the classic regression is a newer sqlite3 rejecting binary message sources.
- Send well-formed mail from apps (proper Content-Type/charset headers) instead of raw sockets when possible.
- When embedding, prefer MailCatcher::Mail.add_message wrapped in your own rescue instead of depending on the internal report.
When it happens
Trigger: Any exception raised inside MailCatcher::Mail.add_message while persisting a received email: SQLite3 errors from the in-memory DB inserts (mail.rb:45-57), Mail.new(source) raising on pathological MIME, or a nil `message[:source]` when receive_message is called without a preceding data chunk; it also prefixes the websocket-send failure logged from application.rb:90.
Common situations: Upgrading the sqlite3 gem past what this MailCatcher version supports (e.g. 1.4.x rejecting strings containing null bytes in the message source); sending mail with broken/8-bit headers or huge attachments from ActionMailer; combining an old mailcatcher gem with a new Ruby; checking the log after seeing SMTP clients get a 451-style failure.
Related errors
- Exception: #{exception}
- Backtrace:
- ~~> ERROR: Something's using port #{port}. Are you already r
- Please submit this as an issue at https://github.com/sj2
- Error receiving message
AI-assisted analysis of sj26/mailcatcher@18a9cb7a79 (2026-08-21).
Data as JSON: /api/errors/6129b7b7d1c3900b.
Report an issue: GitHub.