1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
@file:OptIn(ExperimentalContracts::class)
package moe.nea.firmament.util
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import moe.nea.firmament.Firmament
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
object ErrorUtil {
var aggressiveErrors = run {
TestUtil.isInTest || Firmament.DEBUG
|| ErrorUtil::class.java.desiredAssertionStatus()
}
inline fun softCheck(message: String, check: Boolean) {
if (!check) softError(message)
}
inline fun lazyCheck(message: String, func: () -> Boolean) {
contract {
callsInPlace(func, InvocationKind.AT_MOST_ONCE)
}
if (!aggressiveErrors) return
if (func()) return
error(message)
}
inline fun softError(message: String, exception: Throwable) {
if (aggressiveErrors) throw IllegalStateException(message, exception)
else Firmament.logger.error(message, exception)
}
inline fun softError(message: String) {
if (aggressiveErrors) error(message)
else Firmament.logger.error(message)
}
class Catch<T> private constructor(val value: T?, val exc: Throwable?) {
inline fun or(block: (exc: Throwable) -> T): T {
contract {
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
if (exc != null) return block(exc)
@Suppress("UNCHECKED_CAST")
return value as T
}
companion object {
fun <T> fail(exception: Throwable): Catch<T> = Catch(null, exception)
fun <T> succeed(value: T): Catch<T> = Catch(value, null)
}
}
inline fun <T> catch(message: String, block: () -> T): Catch<T> {
try {
return Catch.succeed(block())
} catch (exc: Throwable) {
softError(message, exc)
return Catch.fail(exc)
}
}
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
contract {
callsInPlace(orElse, InvocationKind.AT_MOST_ONCE)
}
if (nullable == null) {
softError(message)
return orElse()
}
return nullable
}
}
|