You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

exceptions.py 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. # Copyright 2020-2021 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """Define custom exception."""
  16. import abc
  17. import sys
  18. from enum import unique, Enum
  19. from importlib import import_module
  20. from lib2to3.pgen2 import parse
  21. from treelib.exceptions import DuplicatedNodeIdError, MultipleRootError, NodeIDAbsentError
  22. from mindinsight.mindconverter.common.log import logger as log, logger_console as log_console
  23. from mindinsight.utils.constant import ScriptConverterErrors
  24. from mindinsight.utils.exceptions import MindInsightException
  25. @unique
  26. class ConverterErrors(ScriptConverterErrors):
  27. """Converter error codes."""
  28. SCRIPT_NOT_SUPPORT = 1
  29. NODE_TYPE_NOT_SUPPORT = 2
  30. CODE_SYNTAX_ERROR = 3
  31. BASE_CONVERTER_FAIL = 000
  32. GRAPH_INIT_FAIL = 100
  33. TREE_CREATE_FAIL = 200
  34. SOURCE_FILES_SAVE_FAIL = 300
  35. GENERATOR_FAIL = 400
  36. SUB_GRAPH_SEARCHING_FAIL = 500
  37. class ScriptNotSupport(MindInsightException):
  38. """The script can not support to process."""
  39. def __init__(self, msg):
  40. super(ScriptNotSupport, self).__init__(ConverterErrors.SCRIPT_NOT_SUPPORT,
  41. msg,
  42. http_code=400)
  43. class NodeTypeNotSupport(MindInsightException):
  44. """The astNode can not support to process."""
  45. def __init__(self, msg):
  46. super(NodeTypeNotSupport, self).__init__(ConverterErrors.NODE_TYPE_NOT_SUPPORT,
  47. msg,
  48. http_code=400)
  49. class CodeSyntaxError(MindInsightException):
  50. """The CodeSyntaxError class definition."""
  51. def __init__(self, msg):
  52. super(CodeSyntaxError, self).__init__(ConverterErrors.CODE_SYNTAX_ERROR,
  53. msg,
  54. http_code=400)
  55. class MindConverterException(Exception):
  56. """MindConverter exception."""
  57. BASE_ERROR_CODE = None # ConverterErrors.BASE_CONVERTER_FAIL.value
  58. # ERROR_CODE should be declared in child exception.
  59. ERROR_CODE = None
  60. def __init__(self, **kwargs):
  61. """Initialization of MindInsightException."""
  62. user_msg = kwargs.get('user_msg', '')
  63. if isinstance(user_msg, str):
  64. user_msg = ' '.join(user_msg.split())
  65. super(MindConverterException, self).__init__()
  66. self.user_msg = user_msg
  67. self.root_exception_error_code = None
  68. def __str__(self):
  69. return '[{}] code: {}, msg: {}'.format(self.__class__.__name__, self.error_code(), self.user_msg)
  70. def __repr__(self):
  71. return self.__str__()
  72. def error_code(self):
  73. """"
  74. Calculate error code.
  75. code compose(2bytes)
  76. error: 16bits.
  77. num = 0xFFFF & error
  78. error_cods
  79. Returns:
  80. str, Hex string representing the composed MindConverter error code.
  81. """
  82. if self.root_exception_error_code:
  83. return self.root_exception_error_code
  84. if self.BASE_ERROR_CODE is None or self.ERROR_CODE is None:
  85. raise ValueError("MindConverterException has not been initialized.")
  86. num = 0xFFFF & self.ERROR_CODE # 0xFFFF & self.error.value
  87. error_code = f"{str(self.BASE_ERROR_CODE).zfill(3)}{hex(num)[2:].zfill(4).upper()}"
  88. return error_code
  89. @classmethod
  90. @abc.abstractmethod
  91. def raise_from(cls):
  92. """Raise from below exceptions."""
  93. @classmethod
  94. def normalize_error_msg(cls, error_msg):
  95. """Normalize error msg for common python exception."""
  96. if cls.BASE_ERROR_CODE is None or cls.ERROR_CODE is None:
  97. raise ValueError("MindConverterException has not been initialized.")
  98. num = 0xFFFF & cls.ERROR_CODE # 0xFFFF & self.error.value
  99. error_code = f"{str(cls.BASE_ERROR_CODE).zfill(3)}{hex(num)[2:].zfill(4).upper()}"
  100. return f"[{cls.__name__}] code: {error_code}, msg: {error_msg}"
  101. @classmethod
  102. def uniform_catcher(cls, msg: str = ""):
  103. """Uniform exception catcher."""
  104. def decorator(func):
  105. def _f(*args, **kwargs):
  106. try:
  107. res = func(*args, **kwargs)
  108. except cls.raise_from() as e:
  109. error = cls() if not msg else cls(msg=msg)
  110. detail_info = str(e)
  111. if not isinstance(e, MindConverterException):
  112. detail_info = cls.normalize_error_msg(str(e))
  113. log.error(error)
  114. log_console.error("\n")
  115. log_console.error(detail_info)
  116. log_console.error("\n")
  117. log.exception(e)
  118. sys.exit(0)
  119. except ModuleNotFoundError as e:
  120. detail_info = "Error detail: Required package not found, please check the runtime environment."
  121. log_console.error("\n")
  122. log_console.error(str(e))
  123. log_console.error(detail_info)
  124. log_console.error("\n")
  125. log.exception(e)
  126. sys.exit(0)
  127. return res
  128. return _f
  129. return decorator
  130. @classmethod
  131. def check_except(cls, msg):
  132. """Check except."""
  133. def decorator(func):
  134. def _f(*args, **kwargs):
  135. try:
  136. output = func(*args, **kwargs)
  137. except cls.raise_from() as e:
  138. error = cls(msg=msg)
  139. error_code = e.error_code() if isinstance(e, MindConverterException) else None
  140. error.root_exception_error_code = error_code
  141. log.error(msg)
  142. log.exception(e)
  143. raise error
  144. except Exception as e:
  145. log.error(msg)
  146. log.exception(e)
  147. raise e
  148. return output
  149. return _f
  150. return decorator
  151. class BaseConverterError(MindConverterException):
  152. """Base converter failed."""
  153. @unique
  154. class ErrCode(Enum):
  155. """Define error code of BaseConverterError."""
  156. UNKNOWN_ERROR = 0
  157. UNKNOWN_MODEL = 1
  158. PARAM_MISSING = 2
  159. BASE_ERROR_CODE = ConverterErrors.BASE_CONVERTER_FAIL.value
  160. ERROR_CODE = ErrCode.UNKNOWN_ERROR.value
  161. DEFAULT_MSG = "Failed to start base converter."
  162. def __init__(self, msg=DEFAULT_MSG):
  163. super(BaseConverterError, self).__init__(user_msg=msg)
  164. @classmethod
  165. def raise_from(cls):
  166. """Raise from exceptions below."""
  167. except_source = Exception, UnknownModelError, ParamMissingError, cls
  168. return except_source
  169. class UnknownModelError(BaseConverterError):
  170. """The unknown model error."""
  171. ERROR_CODE = BaseConverterError.ErrCode.UNKNOWN_MODEL.value
  172. def __init__(self, msg):
  173. super(UnknownModelError, self).__init__(msg=msg)
  174. @classmethod
  175. def raise_from(cls):
  176. return cls
  177. class ParamMissingError(BaseConverterError):
  178. """Define cli params missing error."""
  179. ERROR_CODE = BaseConverterError.ErrCode.PARAM_MISSING.value
  180. def __init__(self, msg):
  181. super(ParamMissingError, self).__init__(msg=msg)
  182. @classmethod
  183. def raise_from(cls):
  184. return cls
  185. class GraphInitError(MindConverterException):
  186. """The graph init fail error."""
  187. @unique
  188. class ErrCode(Enum):
  189. """Define error code of GraphInitError."""
  190. UNKNOWN_ERROR = 0
  191. MODEL_NOT_SUPPORT = 1
  192. TF_RUNTIME_ERROR = 2
  193. INPUT_SHAPE_ERROR = 3
  194. MI_RUNTIME_ERROR = 4
  195. BASE_ERROR_CODE = ConverterErrors.GRAPH_INIT_FAIL.value
  196. ERROR_CODE = ErrCode.UNKNOWN_ERROR.value
  197. DEFAULT_MSG = "Error occurred when init graph object."
  198. def __init__(self, msg=DEFAULT_MSG):
  199. super(GraphInitError, self).__init__(user_msg=msg)
  200. @classmethod
  201. def raise_from(cls):
  202. """Raise from exceptions below."""
  203. except_source = (FileNotFoundError,
  204. ModuleNotFoundError,
  205. ModelNotSupportError,
  206. ModelLoadingError,
  207. RuntimeIntegrityError,
  208. TypeError,
  209. ZeroDivisionError,
  210. RuntimeError,
  211. cls)
  212. return except_source
  213. class TreeCreationError(MindConverterException):
  214. """The tree create fail."""
  215. @unique
  216. class ErrCode(Enum):
  217. """Define error code of TreeCreationError."""
  218. UNKNOWN_ERROR = 0
  219. NODE_INPUT_MISSING = 1
  220. TREE_NODE_INSERT_FAIL = 2
  221. BASE_ERROR_CODE = ConverterErrors.TREE_CREATE_FAIL.value
  222. ERROR_CODE = ErrCode.UNKNOWN_ERROR.value
  223. DEFAULT_MSG = "Error occurred when create hierarchical tree."
  224. def __init__(self, msg=DEFAULT_MSG):
  225. super(TreeCreationError, self).__init__(user_msg=msg)
  226. @classmethod
  227. def raise_from(cls):
  228. """Raise from exceptions below."""
  229. except_source = NodeInputMissingError, TreeNodeInsertError, cls
  230. return except_source
  231. class SourceFilesSaveError(MindConverterException):
  232. """The source files save fail error."""
  233. @unique
  234. class ErrCode(Enum):
  235. """Define error code of SourceFilesSaveError."""
  236. UNKNOWN_ERROR = 0
  237. NODE_INPUT_TYPE_NOT_SUPPORT = 1
  238. SCRIPT_GENERATE_FAIL = 2
  239. REPORT_GENERATE_FAIL = 3
  240. CKPT_GENERATE_FAIL = 4
  241. MAP_GENERATE_FAIL = 5
  242. BASE_ERROR_CODE = ConverterErrors.SOURCE_FILES_SAVE_FAIL.value
  243. ERROR_CODE = ErrCode.UNKNOWN_ERROR.value
  244. DEFAULT_MSG = "Error occurred when save source files."
  245. def __init__(self, msg=DEFAULT_MSG):
  246. super(SourceFilesSaveError, self).__init__(user_msg=msg)
  247. @classmethod
  248. def raise_from(cls):
  249. """Raise from exceptions below."""
  250. except_source = (NodeInputTypeNotSupportError,
  251. ScriptGenerationError,
  252. ReportGenerationError,
  253. CheckPointGenerationError,
  254. WeightMapGenerationError,
  255. IOError, cls)
  256. return except_source
  257. class ModelNotSupportError(GraphInitError):
  258. """The model not support error."""
  259. ERROR_CODE = GraphInitError.ErrCode.MODEL_NOT_SUPPORT.value
  260. def __init__(self, msg):
  261. super(ModelNotSupportError, self).__init__(msg=msg)
  262. @classmethod
  263. def raise_from(cls):
  264. """Raise from exceptions below."""
  265. onnxruntime_error = getattr(import_module('onnxruntime.capi'), 'onnxruntime_pybind11_state')
  266. except_source = (RuntimeError,
  267. ModuleNotFoundError,
  268. ValueError,
  269. AssertionError,
  270. TypeError,
  271. OSError,
  272. ZeroDivisionError,
  273. onnxruntime_error.Fail,
  274. onnxruntime_error.InvalidArgument,
  275. onnxruntime_error.NoSuchFile,
  276. onnxruntime_error.NoModel,
  277. onnxruntime_error.EngineError,
  278. onnxruntime_error.RuntimeException,
  279. onnxruntime_error.InvalidProtobuf,
  280. onnxruntime_error.ModelLoaded,
  281. onnxruntime_error.NotImplemented,
  282. onnxruntime_error.InvalidGraph,
  283. onnxruntime_error.EPFail,
  284. cls)
  285. return except_source
  286. class TfRuntimeError(GraphInitError):
  287. """Catch tf runtime error."""
  288. ERROR_CODE = GraphInitError.ErrCode.TF_RUNTIME_ERROR.value
  289. DEFAULT_MSG = "Error occurred when init graph, TensorFlow runtime error."
  290. def __init__(self, msg=DEFAULT_MSG):
  291. super(TfRuntimeError, self).__init__(msg=msg)
  292. @classmethod
  293. def raise_from(cls):
  294. tf_error_module = import_module('tensorflow.python.framework.errors_impl')
  295. tf_error = getattr(tf_error_module, 'OpError')
  296. return tf_error, ValueError, RuntimeError, cls
  297. class RuntimeIntegrityError(GraphInitError):
  298. """Catch runtime error."""
  299. ERROR_CODE = GraphInitError.ErrCode.MI_RUNTIME_ERROR.value
  300. def __init__(self, msg):
  301. super(RuntimeIntegrityError, self).__init__(msg=msg)
  302. @classmethod
  303. def raise_from(cls):
  304. return RuntimeError, AttributeError, ImportError, ModuleNotFoundError, cls
  305. class NodeInputMissingError(TreeCreationError):
  306. """The node input missing error."""
  307. ERROR_CODE = TreeCreationError.ErrCode.NODE_INPUT_MISSING.value
  308. def __init__(self, msg):
  309. super(NodeInputMissingError, self).__init__(msg=msg)
  310. @classmethod
  311. def raise_from(cls):
  312. return ValueError, IndexError, KeyError, AttributeError, cls
  313. class TreeNodeInsertError(TreeCreationError):
  314. """The tree node create fail error."""
  315. ERROR_CODE = TreeCreationError.ErrCode.TREE_NODE_INSERT_FAIL.value
  316. def __init__(self, msg):
  317. super(TreeNodeInsertError, self).__init__(msg=msg)
  318. @classmethod
  319. def raise_from(cls):
  320. """Raise from exceptions below."""
  321. except_source = (OSError,
  322. DuplicatedNodeIdError,
  323. MultipleRootError,
  324. NodeIDAbsentError, cls)
  325. return except_source
  326. class NodeInputTypeNotSupportError(SourceFilesSaveError):
  327. """The node input type NOT support error."""
  328. ERROR_CODE = SourceFilesSaveError.ErrCode.NODE_INPUT_TYPE_NOT_SUPPORT.value
  329. def __init__(self, msg):
  330. super(NodeInputTypeNotSupportError, self).__init__(msg=msg)
  331. @classmethod
  332. def raise_from(cls):
  333. return ValueError, TypeError, IndexError, cls
  334. class ScriptGenerationError(SourceFilesSaveError):
  335. """The script generate fail error."""
  336. ERROR_CODE = SourceFilesSaveError.ErrCode.SCRIPT_GENERATE_FAIL.value
  337. def __init__(self, msg):
  338. super(ScriptGenerationError, self).__init__(msg=msg)
  339. @classmethod
  340. def raise_from(cls):
  341. """Raise from exceptions below."""
  342. except_source = (RuntimeError,
  343. parse.ParseError,
  344. AttributeError, cls)
  345. return except_source
  346. class ReportGenerationError(SourceFilesSaveError):
  347. """The report generate fail error."""
  348. ERROR_CODE = SourceFilesSaveError.ErrCode.REPORT_GENERATE_FAIL.value
  349. def __init__(self, msg):
  350. super(ReportGenerationError, self).__init__(msg=msg)
  351. @classmethod
  352. def raise_from(cls):
  353. """Raise from exceptions below."""
  354. return ZeroDivisionError, cls
  355. class CheckPointGenerationError(SourceFilesSaveError):
  356. """The checkpoint generate fail error."""
  357. ERROR_CODE = SourceFilesSaveError.ErrCode.CKPT_GENERATE_FAIL.value
  358. def __init__(self, msg):
  359. super(CheckPointGenerationError, self).__init__(msg=msg)
  360. @classmethod
  361. def raise_from(cls):
  362. """Raise from exceptions below."""
  363. return cls
  364. class WeightMapGenerationError(SourceFilesSaveError):
  365. """The weight names map generate fail error."""
  366. ERROR_CODE = SourceFilesSaveError.ErrCode.MAP_GENERATE_FAIL.value
  367. def __init__(self, msg):
  368. super(WeightMapGenerationError, self).__init__(msg=msg)
  369. @classmethod
  370. def raise_from(cls):
  371. """Raise from exception below."""
  372. return cls
  373. class SubGraphSearchingError(MindConverterException):
  374. """Sub-graph searching exception."""
  375. @unique
  376. class ErrCode(Enum):
  377. """Define error code of SourceFilesSaveError."""
  378. BASE_ERROR = 0
  379. CANNOT_FIND_VALID_PATTERN = 1
  380. MODEL_NOT_SUPPORT = 2
  381. BASE_ERROR_CODE = ConverterErrors.SUB_GRAPH_SEARCHING_FAIL.value
  382. ERROR_CODE = ErrCode.BASE_ERROR.value
  383. DEFAULT_MSG = "Sub-Graph pattern searching fail."
  384. def __init__(self, msg=DEFAULT_MSG):
  385. super(SubGraphSearchingError, self).__init__(user_msg=msg)
  386. @classmethod
  387. def raise_from(cls):
  388. """Define exception in sub-graph searching module."""
  389. return IndexError, KeyError, ValueError, AttributeError, ZeroDivisionError, cls
  390. class GeneratorError(MindConverterException):
  391. """The Generator fail error."""
  392. @unique
  393. class ErrCode(Enum):
  394. """Define error code of SourceFilesSaveError."""
  395. BASE_ERROR = 0
  396. STATEMENT_GENERATION_ERROR = 1
  397. CONVERTED_OPERATOR_LOADING_ERROR = 2
  398. BASE_ERROR_CODE = ConverterErrors.GENERATOR_FAIL.value
  399. ERROR_CODE = ErrCode.BASE_ERROR.value
  400. DEFAULT_MSG = "Error occurred when generate code."
  401. def __init__(self, msg=DEFAULT_MSG):
  402. super(GeneratorError, self).__init__(user_msg=msg)
  403. @classmethod
  404. def raise_from(cls):
  405. """Raise from exceptions below."""
  406. except_source = (ValueError, TypeError, SyntaxError, cls)
  407. return except_source
  408. class ModelLoadingError(GraphInitError):
  409. """Model loading fail."""
  410. ERROR_CODE = GraphInitError.ErrCode.INPUT_SHAPE_ERROR.value
  411. def __init__(self, msg):
  412. super(ModelLoadingError, self).__init__(msg=msg)
  413. @classmethod
  414. def raise_from(cls):
  415. """Define exception when model loading fail."""
  416. return ValueError, cls