Properly return errors to the user

https://awoo.space/@noiob gives "This method requires an authenticated user"
This commit is contained in:
blankie 2023-11-24 18:11:05 +11:00
parent dc3758004b
commit fa68fda5ac
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
2 changed files with 35 additions and 20 deletions

View File

@ -70,12 +70,11 @@ std::optional<Account> MastodonClient::get_account_by_username(const std::string
using namespace std::string_literals; using namespace std::string_literals;
try { try {
std::string resp = this->_send_request("https://"s + host + "/api/v1/accounts/lookup?acct=" + username); Account account = this->_send_request("https://"s + host + "/api/v1/accounts/lookup?acct=" + username);
Account res = nlohmann::json::parse(std::move(resp)); account.same_server = host == account.server;
res.same_server = host == res.server; return account;
return res; } catch (const MastodonException& e) {
} catch (const CurlException& e) { if (e.response_code != 404) {
if (e.code != CURLE_HTTP_RETURNED_ERROR || this->_response_status_code() != 404) {
throw; throw;
} }
@ -86,8 +85,7 @@ std::optional<Account> MastodonClient::get_account_by_username(const std::string
std::vector<Post> MastodonClient::get_pinned_posts(const std::string& host, const std::string& account_id) { std::vector<Post> MastodonClient::get_pinned_posts(const std::string& host, const std::string& account_id) {
using namespace std::string_literals; using namespace std::string_literals;
std::string resp = this->_send_request("https://"s + host + "/api/v1/accounts/" + account_id + "/statuses?pinned=true"); std::vector<Post> posts = this->_send_request("https://"s + host + "/api/v1/accounts/" + account_id + "/statuses?pinned=true");
std::vector<Post> posts = nlohmann::json::parse(std::move(resp));
for (Post& post : posts) { for (Post& post : posts) {
handle_post_server(post, host); handle_post_server(post, host);
@ -114,8 +112,7 @@ std::vector<Post> MastodonClient::get_posts(const std::string& host, const std::
url += '?'; url += '?';
url += query; url += query;
} }
std::string resp = this->_send_request(url); std::vector<Post> posts = this->_send_request(url);
std::vector<Post> posts = nlohmann::json::parse(std::move(resp));
for (Post& post : posts) { for (Post& post : posts) {
handle_post_server(post, host); handle_post_server(post, host);
@ -128,12 +125,11 @@ std::optional<Post> MastodonClient::get_post(const std::string& host, const std:
using namespace std::string_literals; using namespace std::string_literals;
try { try {
std::string resp = this->_send_request("https://"s + host + "/api/v1/statuses/" + id); Post post = this->_send_request("https://"s + host + "/api/v1/statuses/" + id);
Post post = nlohmann::json::parse(std::move(resp));
handle_post_server(post, host); handle_post_server(post, host);
return post; return post;
} catch (const CurlException& e) { } catch (const MastodonException& e) {
if (e.code != CURLE_HTTP_RETURNED_ERROR || this->_response_status_code() != 404) { if (e.response_code != 404) {
throw; throw;
} }
@ -144,8 +140,7 @@ std::optional<Post> MastodonClient::get_post(const std::string& host, const std:
PostContext MastodonClient::get_post_context(const std::string& host, const std::string& id) { PostContext MastodonClient::get_post_context(const std::string& host, const std::string& id) {
using namespace std::string_literals; using namespace std::string_literals;
std::string resp = this->_send_request("https://"s + host + "/api/v1/statuses/" + id + "/context"); PostContext context = this->_send_request("https://"s + host + "/api/v1/statuses/" + id + "/context");
PostContext context = nlohmann::json::parse(std::move(resp));
for (Post& post : context.ancestors) { for (Post& post : context.ancestors) {
handle_post_server(post, host); handle_post_server(post, host);
@ -166,7 +161,6 @@ CURL* MastodonClient::_get_easy() {
} }
try { try {
setopt(curl, CURLOPT_FAILONERROR, 1L);
setopt(curl, CURLOPT_TIMEOUT_MS, 10000L); setopt(curl, CURLOPT_TIMEOUT_MS, 10000L);
setopt(curl, CURLOPT_PROTOCOLS_STR, "https"); setopt(curl, CURLOPT_PROTOCOLS_STR, "https");
setopt(curl, CURLOPT_USERAGENT, "Coyote (https://gitlab.com/blankX/coyote; blankie@nixnetmail.com)"); setopt(curl, CURLOPT_USERAGENT, "Coyote (https://gitlab.com/blankX/coyote; blankie@nixnetmail.com)");
@ -186,7 +180,7 @@ CURL* MastodonClient::_get_easy() {
return curl; return curl;
} }
std::string MastodonClient::_send_request(const std::string& url) { nlohmann::json MastodonClient::_send_request(const std::string& url) {
std::string res; std::string res;
CURL* curl = this->_get_easy(); CURL* curl = this->_get_easy();
@ -198,7 +192,13 @@ std::string MastodonClient::_send_request(const std::string& url) {
throw CurlException(code); throw CurlException(code);
} }
return res; long response_code = this->_response_status_code();
nlohmann::json j = nlohmann::json::parse(std::move(res));
if (response_code != 200) {
throw MastodonException(response_code, j.at("error").get<std::string>());
}
return j;
} }
long MastodonClient::_response_status_code() { long MastodonClient::_response_status_code() {

View File

@ -5,6 +5,7 @@
#include <exception> #include <exception>
#include <pthread.h> #include <pthread.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <nlohmann/json.hpp>
#include "models.h" #include "models.h"
@ -30,6 +31,20 @@ public:
CURLSHcode code; CURLSHcode code;
}; };
class MastodonException : public std::exception {
public:
MastodonException(long response_code_, std::string error) : response_code(response_code_), _error(std::move(error)) {}
const char* what() const noexcept {
return this->_error.c_str();
}
long response_code;
private:
std::string _error;
};
class MastodonClient { class MastodonClient {
public: public:
MastodonClient(const MastodonClient&&) = delete; MastodonClient(const MastodonClient&&) = delete;
@ -58,7 +73,7 @@ public:
private: private:
CURL* _get_easy(); CURL* _get_easy();
std::string _send_request(const std::string& url); nlohmann::json _send_request(const std::string& url);
long _response_status_code(); long _response_status_code();
std::mutex _share_locks[CURL_LOCK_DATA_LAST]; std::mutex _share_locks[CURL_LOCK_DATA_LAST];