Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update signal-cli-rest-api with more verbose error messages and report them #1696

Merged
merged 5 commits into from
Sep 18, 2023

Conversation

mattwr18
Copy link
Contributor

This changes how we report errors with Signal. Previously we just called response.value, which we know will raise an exception if the response is not successful. We then rescued the exception and provided as much context as we could.

  • If this is part of the error message, we want to parse out the challenge token and tag the error with this token so that we can set up a Sentry filter to send this error to a specific channel whose only responsibility will be to alert a dev they need to manually solve a captcha a run signal-cli submitRateLimitChallenge --challenge-token --captcha

docker-compose.yml Outdated Show resolved Hide resolved
else
{}
end
ErrorNotifier.report(exception, context: context, tags: tags)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would include a default here for every other response code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, as I wrote to you in Slack, I think this is overkill and makes it harder to maintain.
The error message now, since you added the stdout to the output can contain several different clues as to why the message failed to send and I don't like the idea of parsing the error messages for several different reasons and doing different things based on that information.

For example, we now have the full message that a number is not registered with Signal any longer if a contributor unregistered their number.

I think it is enough to send the entire message to sentry, as I did:

error_message = JSON.parse(response.body)['error']
exception = SignalAdapter::BadRequestError.new(error_code: response.code, message: error_message)

and continue sending the errors to the #monitoring channel. This channel is for actionable errors that a dev should look into/do something about.

We have another channel #support for non-actionable errors that might require some support from a non-dev.

@@ -19,14 +19,7 @@ def perform(recipient:, text:)
response = Net::HTTP.start(url.host, url.port) do |http|
http.request(request)
end
response.value # may raise exception
rescue Net::HTTPClientException => e
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you remove the rescue then you will not even get to handle_response if an exception is raised.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see from the comment now that response.value may raise the error and it was also removed, nevermind. But I find the behaviour surprising.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I find the behavior as it exists surprising, to be honest. We call response.value because if it is an unsuccessful response calling .value on it raises an exception, we even explain that the only purpose for line 22 is that it may raise an exception.

I think a better way to handle it is to either check the class of the response, or check its code to determine whether the response was successful, or not.

Copy link
Collaborator

@roschaefer roschaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR looks good! Only thing is I would expect a unit test here.

@mattwr18
Copy link
Contributor Author

The PR looks good! Only thing is I would expect a unit test here.

There were actually already unit tests for the sad path, which were failing after the refactor, I've updated them. See 9ad81b3

@mattwr18 mattwr18 changed the title Inspect Signal error message for challenge token keyword Update signal-cli-rest-api with more verbose error messages and report them Sep 13, 2023
mattwr18 and others added 4 commits September 15, 2023 16:09
- If this is part of the error message, we want to parse out the
  challenge token and tag the error with this token so that we can set
up a Sentry filter to send this error to a specific channel whose only
responsibility will be to alert a dev they need to manually solve a
captcha a run signal-cli submitRateLimitChallenge --challenge-token
<TOKEN> --captcha <CAPTCHA>
Co-authored-by: Robert Schäfer <git@roschaefer.de>
- We original talked about tagging the exception so it could be sent to
  a dedicated channel specifically for these rate limit challenge
requests, but as we report all errors, I wanted to keep them all going
to the #monitoring channel. We can monitor that channel with the new
error message and solve the captcha.
@roschaefer roschaefer force-pushed the 1386_add_more_context_to_signal_errors branch from 9ad81b3 to 43e2833 Compare September 15, 2023 14:34
I use the same pattern from this PR here: #1686

Looks like it's always better to pass `URI` instead of `string`: https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTPGenericRequest.html
Because `@uri` and `@host` get initialized.
@roschaefer roschaefer force-pushed the 1386_add_more_context_to_signal_errors branch from 43e2833 to 7cea0c3 Compare September 15, 2023 15:12
url = URI.parse("#{Setting.signal_cli_rest_api_endpoint}/v2/send")
request = Net::HTTP::Post.new(url.to_s, {
uri = URI.parse("#{Setting.signal_cli_rest_api_endpoint}/v2/send")
request = Net::HTTP::Post.new(uri, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It matters that we pass URI not string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is just a copy/paste that survived from code you added d521f28#diff-2e66abeab283cf6d1ae8e78dbcd46410ae0b8eb01361bc44708e1426c6f89f28R31

I don't know why it matters. Maybe, you could further explain


module SignalAdapter
class Api
class << self
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a class with a static method will do. ErrorNotifier is built the same way`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, don't know why I didn't think of that hehe

Copy link
Collaborator

@roschaefer roschaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code-wise, this can be merged. The only critical issue is which image we're going to deploy. Yesterday I was convinced by @mattwr18 to use our own image, because upstream has also unrelated changes, including newer version of signal-cli which causes issues when downgrading.

module SignalAdapter
class BadRequestError < StandardError
def initialize(error_code:, message:)
super("Message was not delivered with error code `#{error_code}` and message `#{message}`")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might become a little unreadable on Sentry in case of multi-line messages, but let's see..

@@ -26,7 +26,7 @@ services:
- postgres_data:/var/lib/postgresql/data

signal:
image: bbernhard/signal-cli-rest-api:0.67
image: bbernhard/signal-cli-rest-api:0.119-dev
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattwr18 Are we going to roll our own image or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think so. There is already a pre-release https://github.com/bbernhard/signal-cli-rest-api/releases/tag/0.68-pre

There, he advises to use this image for testing things out.

@mattwr18 mattwr18 merged commit a5ccdb8 into main Sep 18, 2023
1 check passed
@mattwr18 mattwr18 deleted the 1386_add_more_context_to_signal_errors branch September 18, 2023 18:51
mattwr18 added a commit that referenced this pull request Sep 18, 2023
…xt_to_signal_errors"

This reverts commit a5ccdb8, reversing
changes made to c985028.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants