Skip to content

Commit d2b1ca9

Browse files
authored
FEATURE: log errors when enabling discourse id (#36110)
When admins try to enable discourse id via the site setting, the automated registration process happen in the background. In the case of an error, nothing was bubbled up back to the admin other than an unhelpful error message. On top of that, no errors were logged to help tech-savvy admins to figure out what might be the problem(s). This commit ensures that any error that is happening during the registration process will be logged via the standard Rails logs. On top of that, the error message shown to the admin has been updated to hopefully provide a more helpful description. Ref - https://meta.discourse.org/t/388711
1 parent 864e7b7 commit d2b1ca9

File tree

5 files changed

+68
-14
lines changed

5 files changed

+68
-14
lines changed

app/services/discourse_id/register.rb

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,37 @@ def request_challenge
3333
begin
3434
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl:) { |http| http.request(request) }
3535
rescue StandardError => e
36-
return fail!(error: "Challenge request failed: #{e.message}")
36+
error = "Challenge request to '#{uri}' failed: #{e.message}."
37+
log_error("request_challenge", error)
38+
return fail!(error:)
3739
end
3840

3941
if response.code.to_i != 200
40-
return fail!(error: "Failed to request challenge: #{response.code}\nError: #{response.body}")
42+
error = "Failed to request challenge: #{response.code}\nError: #{response.body}"
43+
log_error("request_challenge", error)
44+
return fail!(error:)
4145
end
4246

4347
begin
4448
json = JSON.parse(response.body)
4549
rescue JSON::ParserError => e
46-
return fail!(error: "Challenge response invalid JSON: #{e.message}")
50+
error = "Challenge response invalid JSON: #{e.message}"
51+
log_error("request_challenge", error)
52+
return fail!(error:)
4753
end
4854

4955
if json["domain"] != Discourse.current_hostname
50-
return fail!(error: "Domain mismatch in challenge response")
56+
error =
57+
"Domain mismatch in challenge response (expected: #{Discourse.current_hostname}, got: #{json["domain"]})"
58+
log_error("request_challenge", error)
59+
return fail!(error:)
5160
end
5261

5362
if Discourse.base_path.present? && json["path"] != Discourse.base_path
54-
return fail!(error: "Path mismatch in challenge response")
63+
error =
64+
"Path mismatch in challenge response (expected: #{Discourse.base_path}, got: #{json["path"]})"
65+
log_error("request_challenge", error)
66+
return fail!(error:)
5567
end
5668

5769
context[:token] = json["token"]
@@ -79,17 +91,23 @@ def register_with_challenge(token:)
7991
begin
8092
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl:) { |http| http.request(request) }
8193
rescue StandardError => e
82-
return fail!(error: "Registration request failed: #{e.message}")
94+
error = "Registration request to '#{uri}' failed: #{e.message}."
95+
log_error("register_with_challenge", error)
96+
return fail!(error:)
8397
end
8498

8599
if response.code.to_i != 200
86-
return fail!(error: "Registration failed: #{response.code}\nError: #{response.body}")
100+
error = "Registration failed: #{response.code}\nError: #{response.body}"
101+
log_error("register_with_challenge", error)
102+
return fail!(error:)
87103
end
88104

89105
begin
90106
context[:data] = JSON.parse(response.body)
91107
rescue JSON::ParserError => e
92-
fail!(error: "Registration response invalid JSON: #{e.message}")
108+
error = "Registration response invalid JSON: #{e.message}"
109+
log_error("register_with_challenge", error)
110+
fail!(error:)
93111
end
94112
end
95113

@@ -101,4 +119,8 @@ def store_credentials(data:)
101119
def discourse_id_url
102120
@url ||= SiteSetting.discourse_id_provider_url.presence || "https://id.discourse.com"
103121
end
122+
123+
def log_error(step, message)
124+
Rails.logger.error("Discourse ID registration failed at step '#{step}'. Error: #{message}")
125+
end
104126
end

config/locales/server.en.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2840,7 +2840,7 @@ en:
28402840
other: "The list must contain exactly %{count} values."
28412841
markdown_linkify_tlds: "You cannot include a value of '*'."
28422842
google_oauth2_hd_groups: "You must configure all 'google oauth2 hd' settings before enabling this setting."
2843-
discourse_id_credentials: "You must configure Discourse ID credentials ('discourse_id_client_id' and 'discourse_id_client_secret') before enabling this setting."
2843+
discourse_id_registration: "Failed to automatically register with Discourse ID. This could be due to network connectivity issues, firewall restrictions, or the Discourse ID service being unreachable. Please check server logs for more details or contact support."
28442844
linkedin_oidc_credentials: "You must configure LinkedIn OIDC credentials ('linkedin_oidc_client_id' and 'linkedin_oidc_client_secret') before enabling this setting."
28452845
search_tokenize_chinese_enabled: "You must disable 'search_tokenize_chinese' before enabling this setting."
28462846
search_tokenize_japanese_enabled: "You must disable 'search_tokenize_japanese' before enabling this setting."

lib/validators/enable_discourse_id_validator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def error_message
2020
if @result&.error.present?
2121
@result.error
2222
elsif credentials_missing?
23-
I18n.t("site_settings.errors.discourse_id_credentials")
23+
I18n.t("site_settings.errors.discourse_id_registration")
2424
end
2525
end
2626

spec/lib/validators/enable_discourse_id_validator_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@
4949
expect(validator.error_message).to eq("an error")
5050
end
5151

52-
it "shows a default error message when something went _very_ wrong" do
52+
it "shows a helpful error message when something went _very_ wrong" do
5353
failed_context = Service::Base::Context.new
5454
failed_context.fail
5555
allow(DiscourseId::Register).to receive(:call).and_return(failed_context)
5656

5757
expect(validator.valid_value?("t")).to eq(false)
5858
expect(validator.error_message).to eq(
59-
I18n.t("site_settings.errors.discourse_id_credentials"),
59+
I18n.t("site_settings.errors.discourse_id_registration"),
6060
)
6161
end
6262
end
@@ -89,14 +89,14 @@
8989
expect(validator.error_message).to eq("another error")
9090
end
9191

92-
it "shows a default error message when something went _very_ wrong" do
92+
it "shows a helpful error message when something went _very_ wrong" do
9393
failed_context = Service::Base::Context.new
9494
failed_context.fail(error: nil)
9595
allow(DiscourseId::Register).to receive(:call).and_return(failed_context)
9696

9797
expect(validator.valid_value?("t")).to eq(false)
9898
expect(validator.error_message).to eq(
99-
I18n.t("site_settings.errors.discourse_id_credentials"),
99+
I18n.t("site_settings.errors.discourse_id_registration"),
100100
)
101101
end
102102
end

spec/services/discourse_id/register_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@
4646
end
4747

4848
it { is_expected.to fail_a_step(:request_challenge) }
49+
50+
it "logs detailed error with context" do
51+
allow(Rails.logger).to receive(:error)
52+
result
53+
expect(Rails.logger).to have_received(:error).with(
54+
/Discourse ID registration failed.*request_challenge.*Network error/m,
55+
)
56+
end
4957
end
5058

5159
context "when challenge request returns non-200 status" do
@@ -57,6 +65,14 @@
5765
end
5866

5967
it { is_expected.to fail_a_step(:request_challenge) }
68+
69+
it "logs error with status code and response body" do
70+
allow(Rails.logger).to receive(:error)
71+
result
72+
expect(Rails.logger).to have_received(:error).with(
73+
/Discourse ID registration failed.*request_challenge.*400.*Bad Request/m,
74+
)
75+
end
6076
end
6177

6278
context "when challenge response is invalid JSON" do
@@ -79,6 +95,14 @@
7995
end
8096

8197
it { is_expected.to fail_a_step(:request_challenge) }
98+
99+
it "logs error with expected and actual domains" do
100+
allow(Rails.logger).to receive(:error)
101+
result
102+
expect(Rails.logger).to have_received(:error).with(
103+
/Discourse ID registration failed.*request_challenge.*Domain mismatch.*expected.*#{Discourse.current_hostname}.*got.*wrong-domain\.com/m,
104+
)
105+
end
82106
end
83107

84108
context "when challenge response has path mismatch" do
@@ -118,6 +142,14 @@
118142
end
119143

120144
it { is_expected.to fail_a_step(:register_with_challenge) }
145+
146+
it "logs detailed error with context" do
147+
allow(Rails.logger).to receive(:error)
148+
result
149+
expect(Rails.logger).to have_received(:error).with(
150+
/Discourse ID registration failed.*register_with_challenge.*Connection timeout/m,
151+
)
152+
end
121153
end
122154

123155
context "when registration returns non-200 status" do

0 commit comments

Comments
 (0)