• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
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
16package escompat;
17
18export class ErrorOptions {
19    cause: Object | undefined = undefined
20
21    constructor(cause: Object | undefined) {
22        this.cause = cause
23    }
24}
25
26/**
27 * Strores information about stacktrace and cause in case of an error.
28 * Serves as a base class for all error classes.
29 */
30export class Error {
31    cause: Object | undefined
32    message: String
33    name: String
34    private stackLines: StackTraceElement[] = []
35    private stack_: String | undefined = undefined
36
37    /**
38    * Constructs a new error instance with provided message and cause
39    *
40    * @param message message of the error
41    *
42    * @param options options of the error
43    */
44    constructor(message?: String, options?: ErrorOptions) {
45        this("Error", message, options)
46    }
47
48
49    /**
50    * Constructs a new error instance with provided message, options and name
51    *
52    * @param name name of the error
53    *
54    * @param message message of the error
55    *
56    * @param options options of the error
57    */
58    constructor(name: String, message: String | undefined, options: ErrorOptions | undefined) {
59        this.message = (message == undefined) ? "" : message
60        this.cause = (options == undefined) ? undefined : options.cause
61        this.name = name
62        this.stackLines = StackTrace.provisionStackTrace()
63    }
64
65    static invoke(message?: String, options?: ErrorOptions): Error {
66        return new Error(message, options)
67    }
68
69    static invoke(message: String): Error {
70        return new Error(message)
71    }
72
73    /**
74    * Converts this error to a string
75    * Result includes error message and the stacktrace
76    *
77    * @returns result of the conversion
78    */
79    override toString(): String {
80        if (this.message != "") {
81            return this.name + ": " + this.message;
82        }
83        return this.name;
84    }
85
86    /**
87    * Forms stack and returns it
88    */
89    get stack(): String | undefined {
90        this.formStack()
91        return this.stack_
92    }
93
94    /**
95    * Cleans up stack lines
96    */
97    set stack(newStack: String | undefined) {
98        this.stack_ = newStack
99        this.stackLines = []
100    }
101
102    /**
103    * Forms stack from this.stackLines and stores it in this.stack_
104    */
105    private formStack() {
106        if (this.stack_ != undefined) {
107            return
108        }
109        if (this.stackLines.length == 0) {
110            return
111        }
112        let builder = new StringBuilder("")
113
114        if (this.message != "") {
115            let val = this.name + ": " + this.message + "\n"
116            builder.append(val)
117        }
118
119        // NOTE(kparshukov): find a better way to erase Error's ctors lines
120        const provisionStackTraceLevel = 2
121        const realStackStart = (this.stackLines.length > provisionStackTraceLevel ? provisionStackTraceLevel : 0)
122        for (let i: int = realStackStart; i < this.stackLines.length; i++) {
123            builder.append(this.stackLines[i].toString() + '\n')
124        }
125
126        this.stack_ = builder.toString()
127        this.stackLines = []
128    }
129}
130