diff --git a/lib/geocoder/lookups/opencagedata.rb b/lib/geocoder/lookups/opencagedata.rb
index 8cb24b4189dd5691914b14c39dd1191c11890713..9e915b7899209c012bf6b891f477bf46dfce5f6e 100644
--- a/lib/geocoder/lookups/opencagedata.rb
+++ b/lib/geocoder/lookups/opencagedata.rb
@@ -18,14 +18,27 @@ module Geocoder::Lookup
 
     private
 
-    def valid_response?(response)
-      status = parse_json(response.body)["status"]
-      super(response) and status['message'] == 'OK'
-    end
-
     def results(query)
-      data = fetch_data(query)
-      (data && data['results']) || []
+      return [] unless doc = fetch_data(query)
+      # return doc["results"]
+      
+      messages = doc['status']['message']
+      case doc['status']['code']
+      when 400 # Error with input
+        raise_error(Geocoder::InvalidRequest, messages) ||
+          warn("Opencagedata Geocoding API error: #{messages}")
+      when 403 # Key related error
+        raise_error(Geocoder::InvalidApiKey, messages) ||
+          warn("Opencagedata Geocoding API error: #{messages}")
+      when 402 # Quata Exceeded
+          raise_error(Geocoder::OverQueryLimitError, messages) ||
+          warn("Opencagedata Geocoding API error: #{messages}")
+      when 500 # Unknown error
+        raise_error(Geocoder::Error, messages) ||
+          warn("Opencagedata Geocoding API error: #{messages}")
+      end
+
+      return doc["results"]
     end
 
     def query_url_params(query)
diff --git a/test/fixtures/opencagedata_invalid_api_key b/test/fixtures/opencagedata_invalid_api_key
new file mode 100644
index 0000000000000000000000000000000000000000..08bd98e2a78ecd8181c7cc669d603550770ea2bb
--- /dev/null
+++ b/test/fixtures/opencagedata_invalid_api_key
@@ -0,0 +1,25 @@
+{
+    "licenses": [
+        {
+            "name": "CC-BY-SA",
+            "url": "http://creativecommons.org/licenses/by-sa/3.0/"
+        },
+        {
+            "name": "ODbL",
+            "url": "http://opendatacommons.org/licenses/odbl/summary/"
+        }
+    ],
+    "results": [ ],
+    "status": {
+        "code": 403,
+        "message": "invalid API key"
+    },
+    "thanks": "For using an OpenCage Data API",
+    "timestamp": {
+        "created_http": "Thu, 07 Aug 2014 14:26:28 GMT",
+        "created_unix": 1407421588
+    },
+    "total_results": 0,
+    "we_are_hiring": "http://lokku.com/#jobs"
+
+}
\ No newline at end of file
diff --git a/test/fixtures/opencagedata_invalid_request b/test/fixtures/opencagedata_invalid_request
new file mode 100644
index 0000000000000000000000000000000000000000..1f6b4884f4348e51d8892cf2a427974f1ebf4b38
--- /dev/null
+++ b/test/fixtures/opencagedata_invalid_request
@@ -0,0 +1,26 @@
+{
+
+    "licenses": [
+        {
+            "name": "CC-BY-SA",
+            "url": "http://creativecommons.org/licenses/by-sa/3.0/"
+        },
+        {
+            "name": "ODbL",
+            "url": "http://opendatacommons.org/licenses/odbl/summary/"
+        }
+    ],
+    "results": [ ],
+    "status": {
+        "code": 400,
+        "message": "Attribute (format) does not pass the type constraint because: not a valid format"
+    },
+    "thanks": "For using an OpenCage Data API",
+    "timestamp": {
+        "created_http": "Thu, 07 Aug 2014 14:27:29 GMT",
+        "created_unix": 1407421649
+    },
+    "total_results": 0,
+    "we_are_hiring": "http://lokku.com/#jobs"
+
+}
\ No newline at end of file
diff --git a/test/fixtures/opencagedata_over_limit b/test/fixtures/opencagedata_over_limit
new file mode 100644
index 0000000000000000000000000000000000000000..d362a22fe2a6513b7e9b0a47e2308c1b6d21dac8
--- /dev/null
+++ b/test/fixtures/opencagedata_over_limit
@@ -0,0 +1,31 @@
+{
+
+    "licenses": [
+        {
+            "name": "CC-BY-SA",
+            "url": "http://creativecommons.org/licenses/by-sa/3.0/"
+        },
+        {
+            "name": "ODbL",
+            "url": "http://opendatacommons.org/licenses/odbl/summary/"
+        }
+    ],
+    "rate": {
+        "limit": 1,
+        "remaining": 0,
+        "reset": null
+    },
+    "results": [ ],
+    "status": {
+        "code": 402,
+        "message": "quota exceeded"
+    },
+    "thanks": "For using an OpenCage Data API",
+    "timestamp": {
+        "created_http": "Thu, 07 Aug 2014 13:59:19 GMT",
+        "created_unix": 1407419959
+    },
+    "total_results": 0,
+    "we_are_hiring": "http://lokku.com/#jobs"
+
+}
\ No newline at end of file
diff --git a/test/unit/lookups/opencagedata_test.rb b/test/unit/lookups/opencagedata_test.rb
index b856a2efcb8f2d2be1c0f04758b931bd1e3a12c5..d92178a1a4beb06dca635f73679fbbe5abb2d16b 100644
--- a/test/unit/lookups/opencagedata_test.rb
+++ b/test/unit/lookups/opencagedata_test.rb
@@ -39,12 +39,26 @@ class OpencagedataTest < GeocoderTestCase
 
 
 
+  def test_raises_exception_when_invalid_request
+    Geocoder.configure(always_raise: [Geocoder::InvalidRequest])
+    assert_raises Geocoder::InvalidRequest do
+      Geocoder.search("invalid request")
+    end
+  end
+
+  def test_raises_exception_when_invalid_api_key
+    Geocoder.configure(always_raise: [Geocoder::InvalidApiKey])
+    assert_raises Geocoder::InvalidApiKey do
+      Geocoder.search("invalid api key")
+    end
+  end
 
-  # def test_raises_exception_when_over_query_limit
-  #   Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
-  #   l = Geocoder::Lookup.get(:opencagedata)
-  #   assert_raises Geocoder::OverQueryLimitError do
-  #     l.send(:results, Geocoder::Query.new("over limit"))
-  #   end
-  # end
+
+  def test_raises_exception_when_over_query_limit
+    Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
+    l = Geocoder::Lookup.get(:opencagedata)
+    assert_raises Geocoder::OverQueryLimitError do
+      l.send(:results, Geocoder::Query.new("over limit"))
+    end
+  end
 end