DMTF/python-redfish-library

Redfish exception handling

Closed this issue · 2 comments

Hello, who can explain and show how to catch redfish exception properly?
Simple except do not reflects real resaon of the issue.

code:

import logging
import redfish
server_ip = ''
login = ''
passwd = ''
try:
    REDFISH_OBJ = redfish.redfish_client(base_url=f"https://{server_ip}", username=login, password=passwd,
                                         default_prefix='/redfish/v1/')
    REDFISH_OBJ.login(auth="session")
except Exception as e:
    error_type = type(e).__name__
    error_message = str(e)
    print(f"An error occurred of type {error_type}: {error_message}")

and it returns
An error occurred of type ServerDownOrUnreachableError: Server not reachable, return code: 403
but the real reason is not activated license

    INFO:redfish.rest.v1:Response Time for GET to /redfish/v1/: 1.2255319170071743 seconds.
DEBUG:redfish.rest.v1:HTTP RESPONSE for /redfish/v1/:
Code: 403 Forbidden

Headers:
	Strict-Transport-Security: max-age=31536000; includeSubdomains
	X-XSS-Protection: 1; mode=block
	X-Frame-Options: SAMEORIGIN
	X-Content-Type-Options: nosniff
	OData-Version: 4.0, 4.0
	Content-Length: 447
	Content-Type: application/json
	Date: Fri, 22 Dec 2023 08:32:24 GMT

Body Response of /redfish/v1/: b'{"error":{"code":"Base.v1_4_0.GeneralError","Message":"A general error has occurred. See ExtendedInfo for more information.","@Message.ExtendedInfo":[{"MessageId":"Base.v1_4_0.OemLicenseNotPassed","Severity":"Warning","Resolution":"Please activate at least one license in above message.","Message":"Not licensed to perform this request. The following licenses SUM DCMS OOB  were needed","MessageArgs":["SUM DCMS OOB "],"RelatedProperties":[""]}]}}'

How catch and handle ""Message":"Not licensed to perform this request. The following licenses SUM DCMS OOB were needed"" properly?
Thank you.

I haven't tested this, but it seems like you should be able to get get additional information specific to the ServerDownOrUnreachableError. That type of exception saves the response object as part of the exception, so you should be able to access the messages in the response as well. Something like this...

try:
    REDFISH_OBJ = redfish.redfish_client(base_url=f"https://{server_ip}", username=login, password=passwd,
                                         default_prefix='/redfish/v1/')
    REDFISH_OBJ.login(auth="session")
except ServerDownOrUnreachableError as e:
    print("Service unavailable")
    print(e.response.text)
except Exception as e:
    # Handle other types of exceptions
    error_type = type(e).__name__
    error_message = str(e)
    print(f"An error occurred of type {error_type}: {error_message}")

As part of the exception handling, you could also use some of the common methods to extract individual messages, such as get_messages_detail or get_error_messages.

Unfortunately the message the service is using for this isn't even valid. The "Base" registry is published by DMTF, and it does not contain a "OemLicenseNotPassed" message identifier. The vendor is illegally extending a standard registry instead of using their own registry for this. It would be good to contact them about this issue.

Got it. Thank you.
I've managed to do it

    REDFISH_OBJ = redfish.redfish_client(base_url=f"https://{server_ip}", username=login, password=passwd,
                                         default_prefix='/redfish/v1/')
    REDFISH_OBJ.login(auth="session")
except redfish.rest.v1.ServerDownOrUnreachableError as e:
    error_type = type(e).__name__
    print(error_type)
    response_json = json.loads(e.response.text)
    error_detail = response_json.get('error')
    if '@Message.ExtendedInfo' in error_detail:
        for info in error_detail['@Message.ExtendedInfo']:
            if 'Message' in info:
                print(f"Error message: {info['Message']}")
except Exception as e:
    error_type = type(e).__name__
    print(f"An error occurred of type: {error_type}")

Output:

Error message: Not licensed to perform this request. The following licenses SUM DCMS OOB  were needed