diff --git a/lib/orientdb4r.rb b/lib/orientdb4r.rb index 06e6d65..de32ca5 100644 --- a/lib/orientdb4r.rb +++ b/lib/orientdb4r.rb @@ -27,6 +27,7 @@ module Binary autoload :RoundRobin, 'orientdb4r/load_balancing' autoload :DocumentMetadata, 'orientdb4r/rest/model' + MUTEX_CLIENT = Mutex.new class << self @@ -42,7 +43,7 @@ def client options={} return options.delete(:binary) ? Binary::BinClient.new(options) : RestClient.new(options) end - Thread.exclusive { + MUTEX_CLIENT.synchronize { client = options.delete(:binary) ? Binary::BinClient.new(options) : RestClient.new(options) Thread.current[:orientdb_client] ||= client #Thread.current[:orientdb_client] ||= BinClient.new options @@ -62,10 +63,18 @@ class OrientdbError < StandardError include ChainedError end + ### + # Error indicating that the request is malformed of invalid somehow. + class InvalidRequestError < OrientdbError; end + ### # Error indicating that access to the resource requires user authentication. class UnauthorizedError < OrientdbError; end + ### + # Error indicating a conflict between database state and the request + class StateConflictError < OrientdbError; end + ### # Error indicating that the server encountered an unexpected condition which prevented it from fulfilling the request. class ServerError < OrientdbError; end diff --git a/lib/orientdb4r/rest/client.rb b/lib/orientdb4r/rest/client.rb index 9a2731e..14cbf90 100644 --- a/lib/orientdb4r/rest/client.rb +++ b/lib/orientdb4r/rest/client.rb @@ -331,9 +331,7 @@ def get_class(name) #:nodoc: raise ArgumentError, "class name is blank" if blank?(name) response = call_server(:method => :get, :uri => "class/#{@database}/#{name}") - rslt = process_response(response) do - raise NotFoundError, 'class not found' if response.body =~ /Invalid class/ - end + rslt = process_response(response) classes = [rslt] decorate_classes_with_model(classes) @@ -348,6 +346,8 @@ def get_class(name) #:nodoc: end clazz + rescue NotFoundError + raise NotFoundError, 'class not found' end @@ -423,8 +423,14 @@ def process_response(response) # return code - if 401 == response.code + if 400 == response.code + raise InvalidRequestError, compose_error_message(response) + elsif 401 == response.code raise UnauthorizedError, compose_error_message(response) + elsif 404 == response.code + raise NotFoundError, compose_error_message(response) + elsif 409 == response.code + raise StateConflictError, compose_error_message(response) elsif 500 == response.code raise ServerError, compose_error_message(response) elsif 2 != (response.code / 100) @@ -455,6 +461,9 @@ def process_response(response) # correspond with expectation. def compose_error_message(http_response, max_len=200) msg = http_response.body.gsub("\n", ' ') + if (matcher = msg.match(/"content": "([^"]+)"/)) + msg = matcher[1] + end msg = "#{msg[0..max_len]} ..." if msg.size > max_len msg end diff --git a/lib/orientdb4r/rest/restclient_node.rb b/lib/orientdb4r/rest/restclient_node.rb index 6423cf3..c82ed37 100644 --- a/lib/orientdb4r/rest/restclient_node.rb +++ b/lib/orientdb4r/rest/restclient_node.rb @@ -39,7 +39,7 @@ def request(options) #:nodoc: # store session ID if received to reuse in next request sessid = response.cookies[SESSION_COOKIE_NAME] - if session_id != sessid and use_session + if sessid and session_id != sessid and use_session @session_id = sessid Orientdb4r::logger.debug "new session id: #{session_id}" end diff --git a/test/test_database.rb b/test/test_database.rb index 59364a7..de3618a 100644 --- a/test/test_database.rb +++ b/test/test_database.rb @@ -80,7 +80,7 @@ def test_create_database @client.get_database :database => 'UniT', :user => 'admin', :password => 'admin' end # creating an existing DB - assert_raise Orientdb4r::ServerError do + assert_raise Orientdb4r::StateConflictError do @client.create_database :database => 'UniT', :user => 'root', :password => DB_ROOT_PASS end # insufficient rights diff --git a/test/test_ddo.rb b/test/test_ddo.rb index da4dcde..9ba107b 100644 --- a/test/test_ddo.rb +++ b/test/test_ddo.rb @@ -93,7 +93,7 @@ def test_create_class_extends assert_equal 'OUser', clazz.super_class # bad super class - assert_raise Orientdb4r::ServerError do @client.create_class(CLASS, :extends => 'nonExistingSuperClass'); end + assert_raise Orientdb4r::InvalidRequestError do @client.create_class(CLASS, :extends => 'nonExistingSuperClass'); end end diff --git a/test/test_dmo.rb b/test/test_dmo.rb index bfc9578..58f414e 100644 --- a/test/test_dmo.rb +++ b/test/test_dmo.rb @@ -49,7 +49,7 @@ def test_insert assert_equal urids.size, @client.query("SELECT FROM #{CLASS} WHERE prop2 = 'linkset'")[0]['friends'].size # table doesn't exist - assert_raise Orientdb4r::ServerError do + assert_raise Orientdb4r::InvalidRequestError do @client.command "INSERT INTO #{CLASS}x (prop1, prop2, friends) VALUES (1, 'linkset', [#{urids.join(',')}])" end # bad syntax @@ -92,7 +92,7 @@ def test_query assert_equal 1, gr.select { |e| e if e['@class'] == 'ORole' }.size # table doesn't exist - assert_raise Orientdb4r::ServerError do + assert_raise Orientdb4r::InvalidRequestError do @client.query 'SELECT FROM OUserX' end # bad syntax @@ -105,7 +105,7 @@ def test_query assert_instance_of Array, entries assert entries.empty? # try to find entry in a non-existing cluster - assert_raise Orientdb4r::ServerError do @client.query 'SELECT FROM #111:1111'; end + assert_raise Orientdb4r::NotFoundError do @client.query 'SELECT FROM #111:1111'; end # used for INSERT assert_raise Orientdb4r::ServerError do @client.query "INSERT INTO #{CLASS} (prop1, prop2, friends) VALUES (0, 'string0', [])" diff --git a/test/test_document_crud.rb b/test/test_document_crud.rb index ac5b353..b46f9e8 100644 --- a/test/test_document_crud.rb +++ b/test/test_document_crud.rb @@ -157,7 +157,7 @@ def test_batch_bad_params doc = @client.create_document( { '@class' => CLASS, 'prop1' => 1, 'prop2' => 'text' }) assert_raise Orientdb4r::ServerError do @client.batch(nil); end assert_raise Orientdb4r::ServerError do @client.batch({:foo => :baz, :bar => :alfa}); end # bad structure - assert_raise Orientdb4r::ServerError do @client.batch({:operations => [{:type => :d, :record => {'@rid' => '#123:456'}}]}); end # bad cluster + assert_raise Orientdb4r::NotFoundError do @client.batch({:operations => [{:type => :d, :record => {'@rid' => '#123:456'}}]}); end # bad cluster assert_nothing_thrown do @client.batch({:operations => [{:type => :d, :record => {'@rid' => "##{doc.doc_rid.cluster_id}:678"}}]}); end # bad RID is not problem end