15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci
45f9996aaSopenharmony_ci#
55f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd.
65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
85f9996aaSopenharmony_ci# You may obtain a copy of the License at
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
115f9996aaSopenharmony_ci#
125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
165f9996aaSopenharmony_ci# limitations under the License.
175f9996aaSopenharmony_ci#
185f9996aaSopenharmony_ci
195f9996aaSopenharmony_ciimport os
205f9996aaSopenharmony_ciimport traceback
215f9996aaSopenharmony_ciimport sys
225f9996aaSopenharmony_cifrom exceptions.ohos_exception import OHOSException
235f9996aaSopenharmony_cifrom util.log_util import LogUtil
245f9996aaSopenharmony_cifrom util.io_util import IoUtil
255f9996aaSopenharmony_cifrom resources.global_var import ROOT_CONFIG_FILE, CURRENT_OHOS_ROOT
265f9996aaSopenharmony_ci
275f9996aaSopenharmony_ci
285f9996aaSopenharmony_cidef throw_exception(func):
295f9996aaSopenharmony_ci    """Description: Function decorator that catch all exception raised by target function,
305f9996aaSopenharmony_ci                please DO NOT use this function directly
315f9996aaSopenharmony_ci    @parameter: "func": The function to be decorated
325f9996aaSopenharmony_ci    @return:None
335f9996aaSopenharmony_ci    @OHOSException: The first digit of the code represents the compilation stage,
345f9996aaSopenharmony_ci        '1', '2', '3', '4' corresponds to preloader, loader, gn, ninja stages respectively
355f9996aaSopenharmony_ci
365f9996aaSopenharmony_ci    Usage:
375f9996aaSopenharmony_ci
385f9996aaSopenharmony_ci    @throw_exception
395f9996aaSopenharmony_ci    def foo():
405f9996aaSopenharmony_ci        ...
415f9996aaSopenharmony_ci        raise OHOSException('SOME ERROR HAPPENDED', '0000')
425f9996aaSopenharmony_ci        ...
435f9996aaSopenharmony_ci
445f9996aaSopenharmony_ci    """
455f9996aaSopenharmony_ci    def wrapper(*args, **kwargs):
465f9996aaSopenharmony_ci        try:
475f9996aaSopenharmony_ci            return func(*args, **kwargs)
485f9996aaSopenharmony_ci        except OHOSException and Exception as exception:
495f9996aaSopenharmony_ci            _code = ''
505f9996aaSopenharmony_ci            _type = ''
515f9996aaSopenharmony_ci            _desc = ''
525f9996aaSopenharmony_ci            _solution = ''
535f9996aaSopenharmony_ci
545f9996aaSopenharmony_ci            if isinstance(exception, OHOSException):
555f9996aaSopenharmony_ci                _code = exception._code
565f9996aaSopenharmony_ci                _type = exception.get_type()
575f9996aaSopenharmony_ci                _desc = exception.get_desc()
585f9996aaSopenharmony_ci                _solution = exception.get_solution()
595f9996aaSopenharmony_ci            else:
605f9996aaSopenharmony_ci                _code = '0000'
615f9996aaSopenharmony_ci                _type = 'UNKNOWN ERROR TYPE'
625f9996aaSopenharmony_ci                _desc = 'NO DESCRIPTION'
635f9996aaSopenharmony_ci                _solution = 'NO SOLUTION'
645f9996aaSopenharmony_ci            if not judge_indep():
655f9996aaSopenharmony_ci                _print_formatted_tracebak(_code, str(exception), _type, _desc, _solution)
665f9996aaSopenharmony_ci            exit(-1)
675f9996aaSopenharmony_ci    return wrapper
685f9996aaSopenharmony_ci
695f9996aaSopenharmony_ci
705f9996aaSopenharmony_cidef judge_indep():
715f9996aaSopenharmony_ci    """Description: judge whether it is related to independent build
725f9996aaSopenharmony_ci    """
735f9996aaSopenharmony_ci    return sys.argv[1] == 'build' and (
745f9996aaSopenharmony_ci            "--indep-build" in sys.argv[2:] or "-i" in sys.argv[2:] or sys.argv[-1] == "-t" or (
755f9996aaSopenharmony_ci            "-t" in sys.argv and sys.argv[sys.argv.index("-t") + 1][0] == '-'))
765f9996aaSopenharmony_ci
775f9996aaSopenharmony_ci
785f9996aaSopenharmony_cidef _print_formatted_tracebak(_code, _exception, _type, _desc, _solution):
795f9996aaSopenharmony_ci    _log_path = ''
805f9996aaSopenharmony_ci    if IoUtil.read_json_file(ROOT_CONFIG_FILE).get('out_path') is not None:
815f9996aaSopenharmony_ci        _log_path = os.path.join(IoUtil.read_json_file(
825f9996aaSopenharmony_ci            ROOT_CONFIG_FILE).get('out_path'), 'build.log')
835f9996aaSopenharmony_ci    else:
845f9996aaSopenharmony_ci        _log_path = os.path.join(CURRENT_OHOS_ROOT, 'out', 'build.log')
855f9996aaSopenharmony_ci    if isinstance(_solution, list):
865f9996aaSopenharmony_ci        _solution = '\n\t\t'.join(str(elem) for elem in _solution)
875f9996aaSopenharmony_ci    LogUtil.write_log(_log_path, traceback.format_exc() + '\n', 'error')
885f9996aaSopenharmony_ci    LogUtil.write_log(_log_path,
895f9996aaSopenharmony_ci                      'Code:        {}'
905f9996aaSopenharmony_ci                      '\n'
915f9996aaSopenharmony_ci                      '\n'
925f9996aaSopenharmony_ci                      'Reason:      {}'
935f9996aaSopenharmony_ci                      '\n'
945f9996aaSopenharmony_ci                      '\n'
955f9996aaSopenharmony_ci                      'Error Type:  {}'
965f9996aaSopenharmony_ci                      '\n'
975f9996aaSopenharmony_ci                      '\n'
985f9996aaSopenharmony_ci                      'Description: {}'
995f9996aaSopenharmony_ci                      '\n'
1005f9996aaSopenharmony_ci                      '\n'
1015f9996aaSopenharmony_ci                      'Solution:    {}'
1025f9996aaSopenharmony_ci                      '\n'
1035f9996aaSopenharmony_ci                      '\n'
1045f9996aaSopenharmony_ci                      .format(_code, _exception, _type, _desc, _solution), 'error')