Improve error displaying, and move error display logic into the error module.
diff --git a/apiclient/errors.py b/apiclient/errors.py
index b3a7d13..6a91e1e 100644
--- a/apiclient/errors.py
+++ b/apiclient/errors.py
@@ -11,6 +11,9 @@
 __author__ = 'jcgregorio@google.com (Joe Gregorio)'
 
 
+from anyjson import simplejson
+
+
 class Error(Exception):
   """Base error for this module."""
   pass
@@ -19,12 +22,28 @@
 class HttpError(Error):
   """HTTP data was invalid or unexpected."""
 
-  def __init__(self, resp, detail):
+  def __init__(self, resp, content):
     self.resp = resp
-    self.detail = detail
+    self.content = content
 
-  def __str__(self):
-    return self.detail
+  def _get_reason(self):
+    """Calculate the reason for the error from the response content.
+    """
+    if self.resp.get('content-type', '').startswith('application/json'):
+      try:
+        data = simplejson.loads(self.content)
+        reason = data['error']['message']
+      except (ValueError, KeyError):
+        reason = self.content
+    else:
+      reason = self.resp.reason
+    return reason
+
+  def __repr__(self):
+    return '<HttpError %s "%s">' % (self.resp.status, self._get_reason())
+
+  __str__ = __repr__
+  
 
 
 class UnknownLinkType(Error):
diff --git a/apiclient/model.py b/apiclient/model.py
index f37a699..cd81c0b 100644
--- a/apiclient/model.py
+++ b/apiclient/model.py
@@ -99,7 +99,4 @@
       return body
     else:
       logging.debug('Content from bad request was: %s' % content)
-      if resp.get('content-type', '').startswith('application/json'):
-        raise HttpError(resp, simplejson.loads(content)['error'])
-      else:
-        raise HttpError(resp, '%d %s' % (resp.status, resp.reason))
+      raise HttpError(resp, content)
diff --git a/tests/test_errors.py b/tests/test_errors.py
new file mode 100644
index 0000000..fbb4778
--- /dev/null
+++ b/tests/test_errors.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2010 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Tests for errors handling
+"""
+
+__author__ = 'afshar@google.com (Ali Afshar)'
+
+
+import unittest
+import httplib2
+
+
+from apiclient.errors import HttpError
+
+
+def fake_response(data, headers):
+  return httplib2.Response(headers), data
+
+
+class Error(unittest.TestCase):
+  """Test handling of error bodies
+  """
+
+  def test_json_body(self):
+    """Test a nicely formed, expected error response
+    """
+    resp, content = fake_response(json_error_content,
+        {'status':'400', 'content-type': 'application/json'})
+    error = HttpError(resp, content)
+    self.assertEqual(str(error), '<HttpError 400 "country is required">')
+
+  def test_bad_json_body(self):
+    """Test handling of bodies with invalid json
+    """
+    resp, content = fake_response('{',
+        {'status':'400', 'content-type': 'application/json'})
+    error = HttpError(resp, content)
+    self.assertEqual(str(error), '<HttpError 400 "{">')
+
+  def test_missing_message_json_body(self):
+    """Test handling of bodies with missing expected 'message' element
+    """
+    resp, content = fake_response('{}',
+        {'status':'400', 'content-type': 'application/json'})
+    error = HttpError(resp, content)
+    self.assertEqual(str(error), '<HttpError 400 "{}">')
+    
+  def test_non_json(self):
+    """Test handling of non-JSON bodies
+    """
+    resp, content = fake_response('NOT OK', {'status':'400'})
+    error = HttpError(resp, content)
+    self.assertEqual(str(error), '<HttpError 400 "Ok">')
+
+
+json_error_content = """
+{
+ "error": {
+  "errors": [
+   {
+    "domain": "global",
+    "reason": "required",
+    "message": "country is required",
+    "locationType": "parameter",
+    "location": "country"
+   }
+  ],
+  "code": 400,
+  "message": "country is required"
+ }
+}
+"""
+