Handle JSONDecodeError and other exception during redfish login

Intermittently, we hit this error

    <class 'json.decoder.JSONDecodeError'>
    Expecting value: line 1 column 1 (char 0)

Observation:
   - redfish 2.1.5 package level gives JSONDecodeError
   - redfish 3.1.1 package for the same raise exception
     redfish.rest.v1.InvalidCredentialsError

After handling and re-try as well, noticed it does seems
to help but gracefully fail and also re-try better success
rate in case of temporary server problems.

Change-Id: Idf29a029b5291ffd2f62ed6cf2729b6485b335a6
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/lib/bmc_redfish.py b/lib/bmc_redfish.py
index 1679ca4..db9e013 100644
--- a/lib/bmc_redfish.py
+++ b/lib/bmc_redfish.py
@@ -9,6 +9,8 @@
 import json
 from redfish_plus import redfish_plus
 from robot.libraries.BuiltIn import BuiltIn
+from json.decoder import JSONDecodeError
+from redfish.rest.v1 import InvalidCredentialsError
 
 import func_args as fa
 import gen_print as gp
@@ -82,8 +84,36 @@
         password, args, kwargs = fa.pop_arg(openbmc_password, *args, **kwargs)
         auth, args, kwargs = fa.pop_arg('session', *args, **kwargs)
 
-        super(bmc_redfish, self).login(username, password, auth,
-                                       *args, **kwargs)
+        try:
+            super(bmc_redfish, self).login(username, password, auth,
+                                           *args, **kwargs)
+        # Handle InvalidCredentialsError.
+        # (raise redfish.rest.v1.InvalidCredentialsError if not [200, 201, 202, 204])
+        except InvalidCredentialsError:
+            except_type, except_value, except_traceback = sys.exc_info()
+            BuiltIn().log_to_console(str(except_type))
+            BuiltIn().log_to_console(str(except_value))
+            e_message = "Re-try login due to exception and "
+            e_message += "it is likely error response from server side."
+            BuiltIn().log_to_console(e_message)
+            super(bmc_redfish, self).login(username, password, auth,
+                                           *args, **kwargs)
+        # Handle JSONDecodeError and others.
+        except JSONDecodeError:
+            except_type, except_value, except_traceback = sys.exc_info()
+            BuiltIn().log_to_console(str(except_type))
+            BuiltIn().log_to_console(str(except_value))
+            e_message = "Re-try login due to JSONDecodeError exception and "
+            e_message += "it is likely error response from server side."
+            BuiltIn().log_to_console(e_message)
+            super(bmc_redfish, self).login(username, password, auth,
+                                           *args, **kwargs)
+        except ValueError:
+            except_type, except_value, except_traceback = sys.exc_info()
+            BuiltIn().log_to_console(str(except_type))
+            BuiltIn().log_to_console(str(except_value))
+            e_message = "Unexpected exception."
+            BuiltIn().log_to_console(e_message)
 
     def logout(self):