-
Notifications
You must be signed in to change notification settings - Fork 1
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
Conversation
else | ||
{} | ||
end | ||
ErrorNotifier.report(exception, context: context, tags: tags) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
There were actually already unit tests for the sad path, which were failing after the refactor, I've updated them. See 9ad81b3 |
- 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.
9ad81b3
to
43e2833
Compare
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.
43e2833
to
7cea0c3
Compare
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, { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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`.
There was a problem hiding this comment.
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
There was a problem hiding this 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}`") |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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.