Skip to content

Commit c71c7af

Browse files
authored
Merge pull request #81 from ImMin5/master
Add exception handler
2 parents 8b87db4 + 8895860 commit c71c7af

File tree

1 file changed

+60
-25
lines changed

1 file changed

+60
-25
lines changed

src/cloudforet/cost_analysis/connector/azure_cost_mgmt_connector.py

+60-25
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import logging
22
import os
33
import time
4-
from datetime import datetime
5-
64
import requests
75
import pandas as pd
86
import numpy as np
7+
from datetime import datetime
8+
from functools import wraps
99
from io import StringIO
10+
from typing import get_type_hints, Union, Any
1011

1112
from azure.identity import DefaultAzureCredential
1213
from azure.mgmt.billing import BillingManagementClient
1314
from azure.mgmt.costmanagement import CostManagementClient
1415
from azure.mgmt.consumption import ConsumptionManagementClient
15-
from azure.core.exceptions import ResourceNotFoundError
16+
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError
1617
from spaceone.core.connector import BaseConnector
1718

1819
from cloudforet.cost_analysis.error.cost import *
@@ -25,6 +26,48 @@
2526
_PAGE_SIZE = 5000
2627

2728

29+
def azure_exception_handler(func):
30+
@wraps(func)
31+
def wrapper(*args, **kwargs) -> Union[dict, list]:
32+
return_type = get_type_hints(func).get("return")
33+
try:
34+
return func(*args, **kwargs)
35+
except ResourceNotFoundError as error:
36+
_print_error_log(error)
37+
return _get_empty_value(return_type)
38+
except HttpResponseError as error:
39+
if error.status_code in ["404", "412"]:
40+
_print_error_log(error)
41+
else:
42+
_print_error_log(error)
43+
return _get_empty_value(return_type)
44+
except Exception as e:
45+
_print_error_log(ERROR_UNKNOWN(message=str(e)))
46+
raise e
47+
48+
return wrapper
49+
50+
51+
def _get_empty_value(return_type: object) -> Any:
52+
return_type_name = getattr(return_type, "__name__")
53+
empty_values = {
54+
"int": 0,
55+
"float": 0.0,
56+
"str": "",
57+
"bool": False,
58+
"list": [],
59+
"dict": {},
60+
"set": set(),
61+
"tuple": (),
62+
}
63+
64+
return empty_values.get(return_type_name, None)
65+
66+
67+
def _print_error_log(error):
68+
_LOGGER.error(f"(Error) => {error.message} {error}", exc_info=True)
69+
70+
2871
class AzureCostMgmtConnector(BaseConnector):
2972
def __init__(self, *args, **kwargs):
3073
super().__init__(*args, **kwargs)
@@ -173,32 +216,24 @@ def get_billing_account(self) -> dict:
173216
billing_account_info = self.convert_nested_dictionary(billing_account_info)
174217
return billing_account_info
175218

219+
@azure_exception_handler
176220
def begin_create_operation(self, scope: str, parameters: dict) -> list:
177-
try:
178-
content_type = "application/json"
179-
response = self.cost_mgmt_client.generate_cost_details_report.begin_create_operation(
221+
content_type = "application/json"
222+
response = (
223+
self.cost_mgmt_client.generate_cost_details_report.begin_create_operation(
180224
scope=scope, parameters=parameters, content_type=content_type
181225
)
182-
result = self.convert_nested_dictionary(response.result())
183-
_LOGGER.info(
184-
f"[begin_create_operation] result : {result} status : {response.status()}"
185-
)
226+
)
227+
result = self.convert_nested_dictionary(response.result())
228+
_LOGGER.info(
229+
f"[begin_create_operation] result : {result} status : {response.status()}"
230+
)
186231

187-
blobs = result.get("blobs", []) or []
188-
_LOGGER.debug(
189-
f"[begin_create_operation] csv_file_link: {blobs} / parameters: {parameters}"
190-
)
191-
return blobs
192-
except ResourceNotFoundError as e:
193-
_LOGGER.error(
194-
f"[begin_create_operation] Cost data is not ready: {e} / parameters: {parameters}"
195-
)
196-
return []
197-
except Exception as e:
198-
_LOGGER.error(
199-
f"[begin_create_operation] error message: {e} / parameters: {parameters}"
200-
)
201-
raise ERROR_UNKNOWN(message=f"[ERROR] begin_create_operation failed")
232+
blobs = result.get("blobs", []) or []
233+
_LOGGER.debug(
234+
f"[begin_create_operation] csv_file_link: {blobs} / parameters: {parameters}"
235+
)
236+
return blobs
202237

203238
def get_cost_data(self, blobs: list, options: dict) -> list:
204239
_LOGGER.debug(f"[get_cost_data] options: {options}")

0 commit comments

Comments
 (0)