rails_error_notifier 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e69205eb4c0a1b6ae43c640efdf0ca492eca18786c0f2d436741b76dae20e000
4
- data.tar.gz: c2dd14cb83881a4463b3a280451789114d3cc419348dbee32fe86f34ccf1f04e
3
+ metadata.gz: d19adf6eb1c84de7e057f7bfab279afc5d98dd68e98c8bdd2c0fe38d584ba112
4
+ data.tar.gz: c0f2eea481b7e3a7cfcbb2dea948a5ed2ebb32b971b18225072c95e61f1a8682
5
5
  SHA512:
6
- metadata.gz: b3b4f45c313196db1cdb0ecf793bfde7dbd24ba1663569d3c1ad6984af3a1f4687dd436d3c1ad3603aadb323912a3249279fc22556b8e56e73b8f00dc38c5dd2
7
- data.tar.gz: f12ee77faf8bfa6e8fe2f63ce8db27c1fe8419da47c480a432e00bcf4c12a14d1e2be749a0a252a623dfc3ec005b60e2e55bd535260eb782d93539a07261db9d
6
+ metadata.gz: 967c4cc629cea743727c124865cc4fdeb1d242e4cb2297bc7f2471f12117b939422ed19f7e538dde92e86021e5b48a01d664b6402693ee46a0ae91b7ca74dd3c
7
+ data.tar.gz: f84ffd0c94b2dde8ffa1f59c10395843b87ab12e08825593f76843186df69d8641b07fa74421669594709feac7e5541165781a85ecbcf126bf118f2dfde1ba5b
@@ -1,11 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This is the initializer for RailsErrorNotifier
4
3
  RailsErrorNotifier.configure do |config|
5
- # Configure your Slack and Discord webhooks via ENV variables
4
+ # Slack + Discord
6
5
  config.slack_webhook = ENV["SLACK_WEBHOOK_URL"]
7
6
  config.discord_webhook = ENV["DISCORD_WEBHOOK_URL"]
8
7
 
9
- # Optional: disable in development/test
8
+ # Email
9
+ config.error_email_to = ENV["ERROR_EMAIL_TO"] # e.g. "dev-team@example.com"
10
+ config.error_email_from = ENV["ERROR_EMAIL_FROM"] # e.g. "notifier@example.com"
11
+
12
+ # WhatsApp (Twilio)
13
+ config.twilio_sid = ENV["TWILIO_SID"]
14
+ config.twilio_token = ENV["TWILIO_TOKEN"]
15
+ config.twilio_from = ENV["TWILIO_FROM"]
16
+ config.twilio_to = ENV["TWILIO_TO"]
17
+
18
+ # Enable only in non-dev/test environments
10
19
  config.enabled = !Rails.env.development? && !Rails.env.test?
11
20
  end
@@ -1,6 +1,14 @@
1
1
  module RailsErrorNotifier
2
2
  class Configuration
3
- attr_accessor :slack_webhook, :discord_webhook, :enabled
3
+ attr_accessor :slack_webhook,
4
+ :discord_webhook,
5
+ :error_email_to,
6
+ :error_email_from,
7
+ :twilio_sid,
8
+ :twilio_token,
9
+ :twilio_from,
10
+ :twilio_to,
11
+ :enabled
4
12
 
5
13
  def initialize
6
14
  @enabled = true
@@ -0,0 +1,21 @@
1
+ require "action_mailer"
2
+ module RailsErrorNotifier
3
+ class ErrorNotifierMailer < ActionMailer::Base
4
+ default from: -> { RailsErrorNotifier.configuration.error_email_from || "errors@example.com" }
5
+
6
+ def error_notification(error:, backtrace:, context:)
7
+ @error = error
8
+ @backtrace = backtrace
9
+ @context = context
10
+
11
+ # Set the view path to the gem's templates
12
+ view_path = File.join(File.dirname(__FILE__), "views")
13
+ prepend_view_path(view_path) if File.exist?(view_path)
14
+
15
+ mail(
16
+ to: RailsErrorNotifier.configuration.error_email_to || "devs@example.com",
17
+ subject: "[RailsErrorNotifier] #{error.truncate(50)}"
18
+ )
19
+ end
20
+ end
21
+ end
@@ -1,8 +1,11 @@
1
1
  require "net/http"
2
2
  require "json"
3
+ require "twilio-ruby"
4
+ # require "time"
3
5
 
4
6
  module RailsErrorNotifier
5
7
  class Notifier
8
+ MAX_FIELD_VALUE = 1024
6
9
  attr_reader :exception, :context
7
10
 
8
11
  def initialize(exception, context = {})
@@ -15,16 +18,27 @@ module RailsErrorNotifier
15
18
 
16
19
  payload = {
17
20
  error: exception.message,
18
- backtrace: exception.backtrace,
19
- context: context
21
+ backtrace: exception.backtrace || ["No backtrace"],
22
+ context: context || {}
20
23
  }
21
24
 
25
+ # Slack + Discord
22
26
  send_to_webhook(RailsErrorNotifier.configuration.slack_webhook, payload)
23
27
  send_to_webhook(RailsErrorNotifier.configuration.discord_webhook, payload)
28
+
29
+ # Email (Rails Mailer)
30
+ send_to_email(payload)
31
+
32
+ # WhatsApp (Twilio)
33
+ send_to_whatsapp(payload)
24
34
  end
25
35
 
26
36
  private
27
37
 
38
+ def truncate_for_discord(text)
39
+ text[0, MAX_FIELD_VALUE - 10] # leave room for ``` block
40
+ end
41
+
28
42
  def send_to_webhook(url, payload)
29
43
  return unless url
30
44
  uri = URI(url)
@@ -32,10 +46,62 @@ module RailsErrorNotifier
32
46
  data = if url.include?("hooks.slack.com")
33
47
  { text: "#{payload[:error]}\n#{payload[:backtrace].join("\n")}" }
34
48
  else
35
- payload
49
+ backtrace_text = truncate_for_discord((payload[:backtrace] || ["No backtrace"]).first(10).join("\n"))
50
+ context_text = truncate_for_discord(payload[:context].inspect)
51
+ {
52
+ username: "RailsErrorNotifier",
53
+ embeds: [
54
+ {
55
+ title: "🚨 Error Occurred",
56
+ description: payload[:error],
57
+ color: 0xFF0000,
58
+ fields: [
59
+ { name: "Backtrace", value: "```\n#{backtrace_text}\n```", inline: false },
60
+ { name: "Context", value: "```\n#{context_text}\n```", inline: false }
61
+ ],
62
+ timestamp: Time.now.utc.iso8601
63
+ }
64
+ ]
65
+ }
36
66
  end
37
67
 
38
68
  Net::HTTP.post(uri, data.to_json, "Content-Type" => "application/json")
69
+ rescue => e
70
+ warn "[RailsErrorNotifier] Slack/Discord delivery failed: #{e.message}"
71
+ nil
72
+ end
73
+
74
+ def send_to_email(payload)
75
+ return unless defined?(RailsErrorNotifier::ErrorNotifierMailer)
76
+
77
+ RailsErrorNotifier::ErrorNotifierMailer.error_notification(
78
+ error: payload[:error],
79
+ backtrace: payload[:backtrace],
80
+ context: payload[:context]
81
+ ).deliver_now
82
+ rescue => e
83
+ warn "[RailsErrorNotifier] Email delivery failed: #{e.message}"
84
+ nil
85
+ end
86
+
87
+ def send_to_whatsapp(payload)
88
+ cfg = RailsErrorNotifier.configuration
89
+ return unless cfg&.twilio_sid && cfg&.twilio_token
90
+
91
+ client = Twilio::REST::Client.new(cfg.twilio_sid, cfg.twilio_token)
92
+
93
+ message = "🚨 Error: #{payload[:error]}\n" \
94
+ "Backtrace: #{payload[:backtrace].first}\n" \
95
+ "Context: #{payload[:context].inspect}"
96
+
97
+ client.messages.create(
98
+ from: "whatsapp:#{cfg.twilio_from}",
99
+ to: "whatsapp:#{cfg.twilio_to}",
100
+ body: message
101
+ )
102
+ rescue => e
103
+ warn "[RailsErrorNotifier] WhatsApp delivery failed: #{e.message}"
104
+ nil
39
105
  end
40
106
  end
41
107
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsErrorNotifier
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
@@ -0,0 +1,24 @@
1
+ <h2 style="color: #d32f2f; font-family: Arial, sans-serif;">🚨 Error Notification</h2>
2
+
3
+ <div style="background: #fff3e0; border-left: 4px solid #ff9800; padding: 15px; margin: 10px 0;">
4
+ <h3 style="margin-top: 0; color: #e65100;">Error Details</h3>
5
+ <p style="font-family: monospace; background: #f5f5f5; padding: 10px; border-radius: 4px; word-break: break-all;">
6
+ <%= @error %>
7
+ </p>
8
+ </div>
9
+
10
+ <div style="margin: 20px 0;">
11
+ <h3 style="color: #1976d2;">Backtrace</h3>
12
+ <pre style="background: #f8f9fa; padding: 15px; border-radius: 6px; border: 1px solid #e9ecef; overflow-x: auto; font-size: 12px; line-height: 1.4;"><%= Array(@backtrace).join("\n") %></pre>
13
+ </div>
14
+
15
+ <% if @context.present? %>
16
+ <div style="margin: 20px 0;">
17
+ <h3 style="color: #388e3c;">Context Information</h3>
18
+ <pre style="background: #e8f5e8; padding: 15px; border-radius: 6px; border: 1px solid #c8e6c9; overflow-x: auto; font-size: 12px; line-height: 1.4;"><%= @context.inspect %></pre>
19
+ </div>
20
+ <% end %>
21
+
22
+ <div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd; color: #666; font-size: 12px;">
23
+ <p>This error was automatically reported by RailsErrorNotifier at <%= Time.current.strftime("%Y-%m-%d %H:%M:%S UTC") %></p>
24
+ </div>
@@ -0,0 +1,17 @@
1
+ 🚨 ERROR NOTIFICATION
2
+ ====================
3
+
4
+ Error: <%= @error %>
5
+
6
+ Backtrace:
7
+ ----------
8
+ <%= Array(@backtrace).join("\n") %>
9
+
10
+ <% if @context.present? %>
11
+ Context:
12
+ --------
13
+ <%= @context.inspect %>
14
+ <% end %>
15
+
16
+ ---
17
+ This error was automatically reported by RailsErrorNotifier at <%= Time.current.strftime("%Y-%m-%d %H:%M:%S UTC") %>
@@ -1,5 +1,6 @@
1
1
  require "rails_error_notifier/configuration"
2
2
  require "rails_error_notifier/notifier"
3
+ require "rails_error_notifier/error_notifier_mailer"
3
4
  require "rails_error_notifier/middleware"
4
5
  require "rails_error_notifier/railtie" if defined?(Rails::Railtie)
5
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_error_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - mrmalvi
@@ -25,10 +25,13 @@ files:
25
25
  - lib/generators/rails_error_notifier/templates/rails_error_notifier.rb
26
26
  - lib/rails_error_notifier.rb
27
27
  - lib/rails_error_notifier/configuration.rb
28
+ - lib/rails_error_notifier/error_notifier_mailer.rb
28
29
  - lib/rails_error_notifier/middleware.rb
29
30
  - lib/rails_error_notifier/notifier.rb
30
31
  - lib/rails_error_notifier/railtie.rb
31
32
  - lib/rails_error_notifier/version.rb
33
+ - lib/rails_error_notifier/views/rails_error_notifier/error_notifier_mailer/error_notification.html.erb
34
+ - lib/rails_error_notifier/views/rails_error_notifier/error_notifier_mailer/error_notification.text.erb
32
35
  - sig/rails_error_notifier.rbs
33
36
  - test/test_helper.rb
34
37
  - test/test_rails_error_notifier.rb