Passing an api_username for a user that does not exist returns a 500 with no useful context


#1

On the beta branch, when attempting to create a POST on behalf of a user, I use the API and provide the username as the api_username. Because of the way I’m managing users, the user may not exist in Discourse at this time and I’d like to be able to respond to that exception by creating the user. It would be useful if the error had enough context to determine that this case occurred, but instead, it’s raising a Discourse::InvalidAccess and the server is returning a 500.

Strack trace:

lib/auth/default_current_user_provider.rb:57:in `current_user'
lib/current_user.rb:30:in `current_user'
app/helpers/application_helper.rb:59:in `html_classes'
app/views/layouts/application.html.erb:2:in `_app_views_layouts_application_html_erb__210758119167932006_91259420'
app/controllers/application_controller.rb:496:in `build_not_found_page'
app/controllers/application_controller.rb:134:in `rescue_discourse_actions'
app/controllers/application_controller.rb:117:in `block in <class:ApplicationController>'
config/initializers/100-quiet_logger.rb:13:in `call_with_quiet_assets'
config/initializers/100-silence_logger.rb:26:in `call'
lib/middleware/missing_avatars.rb:21:in `call'
lib/middleware/turbo_dev.rb:33:in `call'

I can work around this, but it would be nice if the server responded with something in the 4xx range and enough information to determine the cause of the issue.


(Jeff Atwood) #2

Sure I am all for better, more descriptive errors – @techapj can you add to your list?


#3

Just curious, is there an issue or something else I can follow related to this bug? I have a bit of code to work around it that I’d like to rip out once I know that I can :slight_smile:


(Jeff Atwood) #4

I am confident @techapj will get to it in due time.


(Arpit Jalan) #5

This is actually by design as per:

I believe Discourse::InvalidAccess is enough to determine that

  • either username is incorrect
  • or api_key is incorrect

If both of the above is correct than you will get specific error message.

I hope this helps.


#6

Thanks for the reply. In my tests, it would reply with a 500 with no
response body. It’s impossible to know the reason for the failure in that
case. I would think something in the 4xx range with some information
indicating the cause of the error (a username that does not exist) would be
more helpful and appropriate, no?


(Arpit Jalan) #7

Are you using official discourse_api gem?

I just tried the same using official discourse_api and got 403 Forbidden with proper error message:

{"errors"=>["You are not permitted to view the requested resource."], "error_type"=>"invalid_access"} (DiscourseApi::UnauthenticatedError)

#8

No, I’m just hitting the API via HTTP. I’ll provide a CURL command when I’m
back to my computer.


#9

Here’s an example curl command with sensitive data stripped out:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'raw=demo of failing post on behalf of non-existent api-user&title=herp derp jerp' "<my_discourse_instance>/posts?api_key=<valid_api_key>&api_username=<nonexistent_username>" -i

(Arpit Jalan) #10

Try making cURL request in this format:

curl -X POST -H "Accept: application/json" -H "Content-Type: application/json" -d '{"raw":"demo of success post"}' <my_discourse_instance>/posts?api_key=<valid_api_key>&api_username=<nonexistent_username>

You will get exact response and error message you are looking for.