From b0d02de72fa5d5c3b23eee2f0be28edffba7c0dc Mon Sep 17 00:00:00 2001 From: Sunny Ripert Date: Tue, 3 Jan 2023 13:14:07 +0100 Subject: [PATCH] Add custom exception for error responses --- lib/thingiverse.rb | 1 + lib/thingiverse/connection.rb | 4 ++-- lib/thingiverse/pagination.rb | 17 ++++++++--------- lib/thingiverse/response_error.rb | 19 +++++++++++++++++++ lib/thingiverse/tags.rb | 4 ++-- lib/thingiverse/things.rb | 22 +++++++++++----------- lib/thingiverse/users.rb | 4 ++-- 7 files changed, 45 insertions(+), 26 deletions(-) create mode 100644 lib/thingiverse/response_error.rb diff --git a/lib/thingiverse.rb b/lib/thingiverse.rb index 3bb328f..99428c3 100644 --- a/lib/thingiverse.rb +++ b/lib/thingiverse.rb @@ -7,6 +7,7 @@ require 'thingiverse/dynamic_attributes' require 'thingiverse/connection' +require 'thingiverse/response_error' require 'thingiverse/pagination' require 'thingiverse/things' require 'thingiverse/files' diff --git a/lib/thingiverse/connection.rb b/lib/thingiverse/connection.rb index 89bfc79..da50e8d 100644 --- a/lib/thingiverse/connection.rb +++ b/lib/thingiverse/connection.rb @@ -35,7 +35,7 @@ def access_token=(token) def get_token auth_response = self.class.post(auth_url, :query => {:client_id => @client_id, :client_secret => @client_secret, :code => @code}) - raise "#{auth_response.code}: #{auth_response.body.inspect}" unless auth_response.success? + raise ResponseError.new(auth_response) unless auth_response.success? response = CGI::parse(auth_response.parsed_response) @@ -53,7 +53,7 @@ def things def users Thingiverse::Users end - + def tags Thingiverse::Tags end diff --git a/lib/thingiverse/pagination.rb b/lib/thingiverse/pagination.rb index ab33ad5..7f7aa17 100644 --- a/lib/thingiverse/pagination.rb +++ b/lib/thingiverse/pagination.rb @@ -4,17 +4,16 @@ module Thingiverse class Pagination include Enumerable extend Forwardable - + attr_reader :response, :object attr_reader :current_page, :total_pages, :first_url, :last_url, :next_url, :prev_url - + def initialize(response, object) @response = response @object = object - # TODO: provide more debug info and raise a custom exception - raise "#{@response.code}: #{JSON.parse(@response.body)['error']}" unless @response.success? - + raise ResponseError.new(@response) unless @response.success? + @objects = @response.parsed_response.collect do |attrs| @object.new attrs end @@ -38,7 +37,7 @@ def initialize(response, object) end def_delegators :@objects, :<<, :[], :[]=, :last, :size - + def method_missing(meth, *args, &block) if meth.to_s =~ /^(.*)_page$/ get_url_page($1, *args, &block) @@ -46,14 +45,14 @@ def method_missing(meth, *args, &block) super end end - + def get_url_page(which, *args, &block) url = instance_variable_get("@#{which}_url") Thingiverse::Pagination.new(Thingiverse::Connection.get(url), @object) if url end - + def each(&block) @objects.each(&block) - end + end end end diff --git a/lib/thingiverse/response_error.rb b/lib/thingiverse/response_error.rb new file mode 100644 index 0000000..2df9a86 --- /dev/null +++ b/lib/thingiverse/response_error.rb @@ -0,0 +1,19 @@ +module Thingiverse + class ResponseError < StandardError + def initialize(response) + @response = response + end + + attr_reader :response + + def message + "#{response.code}: #{message_body} #{response.headers['x-error']}".strip + end + + def message_body + JSON.parse(response.body)['error'] + rescue + response.body + end + end +end diff --git a/lib/thingiverse/tags.rb b/lib/thingiverse/tags.rb index 91bc852..70eec53 100644 --- a/lib/thingiverse/tags.rb +++ b/lib/thingiverse/tags.rb @@ -4,10 +4,10 @@ class Tags def self.find(tag_name) response = Thingiverse::Connection.get("/tags/#{tag_name}") - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? self.new response.parsed_response end - + def things(query = {}) Thingiverse::Pagination.new(Thingiverse::Connection.get(things_url, :query => query), Thingiverse::Things) end diff --git a/lib/thingiverse/things.rb b/lib/thingiverse/things.rb index 3d3864a..5a042ee 100644 --- a/lib/thingiverse/things.rb +++ b/lib/thingiverse/things.rb @@ -4,7 +4,7 @@ class Things def user response = Thingiverse::Connection.get("/users/#{creator['name']}") - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? Thingiverse::Users.new response.parsed_response end @@ -26,7 +26,7 @@ def ancestors(query = {}) def tags response = Thingiverse::Connection.get(tags_url) - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? response.parsed_response.collect do |attrs| Thingiverse::Tags.new attrs end @@ -37,7 +37,7 @@ def save thing = Thingiverse::Things.create(@attributes) else response = Thingiverse::Connection.patch("/things/#{id}", :body => @attributes.to_json) - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? thing = Thingiverse::Things.new(response.parsed_response) end @@ -46,7 +46,7 @@ def save send("#{name}=", value) end end - + # file_or_string can be a File or a String. # thingiverse_filename is optional if using a File (the File filename will be used by default) but is required if using a String def upload(file_or_string, thingiverse_filename=nil) @@ -59,11 +59,11 @@ def upload(file_or_string, thingiverse_filename=nil) else raise ArgumentError, "file_or_string not of accepted type. Expected File or String. Actual: #{file_or_string.class}" end - + raise ArgumentError, "Unable to determine filename" if thingiverse_filename.to_s == "" - + response = Thingiverse::Connection.post("/things/#{id}/files", :body => {:filename => thingiverse_filename}.to_json) - raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success? + raise ResponseError.new(response) unless response.success? parsed_response = JSON.parse(response.body) action = parsed_response["action"] @@ -96,7 +96,7 @@ def upload(file_or_string, thingiverse_filename=nil) if c.response_code == 303 # finalize it response = Thingiverse::Connection.post(query['success_action_redirect']) - raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success? + raise ResponseError.new(response) unless response.success? Thingiverse::Files.new(response.parsed_response) else raise "#{c.response_code}: #{c.body_str}" @@ -108,7 +108,7 @@ def publish raise "Cannot publish until thing is saved" else response = Thingiverse::Connection.post("/things/#{id}/publish") - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? thing = Thingiverse::Things.new(response.parsed_response) end @@ -120,7 +120,7 @@ def publish def self.find(thing_id) response = Thingiverse::Connection.get("/things/#{thing_id}") - raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success? + raise ResponseError.new(response) unless response.success? self.new response.parsed_response end @@ -132,7 +132,7 @@ def self.create(params) thing = self.new(params) response = Thingiverse::Connection.post('/things', :body => thing.attributes.to_json) - raise "#{response.code}: #{JSON.parse(response.body)['error']} #{response.headers['x-error']}" unless response.success? + raise ResponseError.new(response) unless response.success? self.new(response.parsed_response) end diff --git a/lib/thingiverse/users.rb b/lib/thingiverse/users.rb index 1f12bc8..4d3a3a1 100644 --- a/lib/thingiverse/users.rb +++ b/lib/thingiverse/users.rb @@ -1,10 +1,10 @@ module Thingiverse class Users include Thingiverse::DynamicAttributes - + def self.find(user_name) response = Thingiverse::Connection.get("/users/#{user_name}") - raise "#{response.code}: #{JSON.parse(response.body)['error']}" unless response.success? + raise ResponseError.new(response) unless response.success? self.new response.parsed_response end end