[mq]: smallfixes
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index c54b57f..3e1964c 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -267,6 +267,8 @@
     if type(value) == type('') or type(value) == type(u''):
       return value
     else:
+      if value is None:
+        raise ValueError('String parameters can not be None.')
       return str(value)
   elif schema_type == 'integer':
     return str(int(value))
diff --git a/oauth2client/client.py b/oauth2client/client.py
index 5d92b86..d8eaf69 100644
--- a/oauth2client/client.py
+++ b/oauth2client/client.py
@@ -593,7 +593,7 @@
     body = self._generate_refresh_request_body()
     headers = self._generate_refresh_request_headers()
 
-    logger.info('Refresing access_token')
+    logger.info('Refreshing access_token')
     resp, content = http_request(
         self.token_uri, method='POST', body=body, headers=headers)
     if resp.status == 200:
@@ -1028,10 +1028,24 @@
         of the query parameters to the redirect_uri, which contains
         the code.
       http: httplib2.Http, optional http instance to use to do the fetch
+
+    Returns:
+      An OAuth2Credentials object that can be used to authorize requests.
+
+    Raises:
+      FlowExchangeError if a problem occured exchanging the code for a
+      refresh_token.
     """
 
     if not (isinstance(code, str) or isinstance(code, unicode)):
-      code = code['code']
+      if 'code' not in code:
+        if 'error' in code:
+          error_msg = code['error']
+        else:
+          error_msg = 'No code was supplied in the query parameters.'
+        raise FlowExchangeError(error_msg)
+      else:
+        code = code['code']
 
     body = urllib.urlencode({
         'grant_type': 'authorization_code',
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 5970970..91db712 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -193,6 +193,16 @@
     self.assertEqual(q['trace'], ['html'])
     self.assertEqual(q['fields'], ['description'])
 
+  def test_string_params_none_is_invalid(self):
+    http = HttpMock(datafile('zoo.json'), {'status': '200'})
+    zoo = build('zoo', 'v1', http)
+    # String isn't None
+    try:
+      request = zoo.query(trace=None, fields='description')
+      self.fail()
+    except ValueError, e:
+      self.assertTrue('None' in str(e))
+
   def test_model_added_query_parameters(self):
     http = HttpMock(datafile('zoo.json'), {'status': '200'})
     zoo = build('zoo', 'v1', http)
diff --git a/tests/test_oauth2client.py b/tests/test_oauth2client.py
index cb1b4b3..eb2d7db 100644
--- a/tests/test_oauth2client.py
+++ b/tests/test_oauth2client.py
@@ -279,6 +279,19 @@
     credentials = self.flow.step2_exchange('some random code', http)
     self.assertEqual(None, credentials.token_expiry)
 
+  def test_exchange_fails_if_no_code(self):
+    http = HttpMockSequence([
+      ({'status': '200'}, """{ "access_token":"SlAV32hkKG",
+       "refresh_token":"8xLOxBtZp8" }"""),
+      ])
+
+    code = {'error': 'thou shall not pass'}
+    try:
+      credentials = self.flow.step2_exchange(code, http)
+      self.fail('should raise exception if no code in dictionary.')
+    except FlowExchangeError, e:
+      self.assertTrue('shall not pass' in str(e))
+
   def test_exchange_id_token_fail(self):
     http = HttpMockSequence([
       ({'status': '200'}, """{ "access_token":"SlAV32hkKG",