Error -> Defect for defects (#13908)

* Error -> Defect for defects

The distinction between Error and Defect is subjective,
context-dependent and somewhat arbitrary, so when looking at an
exception, it's hard to guess what it is - this happens often when
looking at a `raises` list _without_ opening the corresponding
definition and digging through layers of inheritance.

With the help of a little consistency in naming, it's at least possible
to start disentangling the two error types and the standard lib can set
a good example here.
This commit is contained in:
Jacek Sieka 2020-04-28 19:56:01 +02:00 • committed by GitHub
commit 7d6cbf290a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
92 changed files with 323 additions and 300 deletions

View file

@ -75,14 +75,14 @@ template fillImpl[T](a: var openArray[T], first, last: int, value: T) =
proc fill*[T](a: var openArray[T], first, last: Natural, value: T) =
## Fills the slice ``a[first..last]`` with ``value``.
##
## If an invalid range is passed, it raises IndexError.
## If an invalid range is passed, it raises IndexDefect.
runnableExamples:
var a: array[6, int]
a.fill(1, 3, 9)
assert a == [0, 9, 9, 9, 0, 0]
a.fill(3, 5, 7)
assert a == [0, 9, 9, 7, 7, 7]
doAssertRaises(IndexError, a.fill(1, 7, 9))
doAssertRaises(IndexDefect, a.fill(1, 7, 9))
fillImpl(a, first, last, value)
proc fill*[T](a: var openArray[T], value: T) =
@ -99,7 +99,7 @@ proc fill*[T](a: var openArray[T], value: T) =
proc reverse*[T](a: var openArray[T], first, last: Natural) =
## Reverses the slice ``a[first..last]``.
##
## If an invalid range is passed, it raises IndexError.
## If an invalid range is passed, it raises IndexDefect.
##
## **See also:**
## * `reversed proc<#reversed,openArray[T],Natural,int>`_ reverse a slice and returns a ``seq[T]``
@ -110,7 +110,7 @@ proc reverse*[T](a: var openArray[T], first, last: Natural) =
assert a == [1, 4, 3, 2, 5, 6]
a.reverse(1, 3)
assert a == [1, 2, 3, 4, 5, 6]
doAssertRaises(IndexError, a.reverse(1, 7))
doAssertRaises(IndexDefect, a.reverse(1, 7))
var x = first
var y = last
while x < y:
@ -135,7 +135,7 @@ proc reverse*[T](a: var openArray[T]) =
proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T] =
## Returns the reverse of the slice ``a[first..last]``.
##
## If an invalid range is passed, it raises IndexError.
## If an invalid range is passed, it raises IndexDefect.
##
## **See also:**
## * `reverse proc<#reverse,openArray[T],Natural,Natural>`_ reverse a slice
@ -238,7 +238,7 @@ proc lowerBound*[T, K](a: openArray[T], key: K, cmp: proc(x: T, k: K): int {.
## ``insert(thing, elm, lowerBound(thing, elm))``
## the sequence will still be sorted.
##
## If an invalid range is passed, it raises IndexError.
## If an invalid range is passed, it raises IndexDefect.
##
## The version uses ``cmp`` to compare the elements.
## The expected return values are the same as that of ``system.cmp``.
@ -286,7 +286,7 @@ proc upperBound*[T, K](a: openArray[T], key: K, cmp: proc(x: T, k: K): int {.
## ``insert(thing, elm, upperBound(thing, elm))``
## the sequence will still be sorted.
##
## If an invalid range is passed, it raises IndexError.
## If an invalid range is passed, it raises IndexDefect.
##
## The version uses ``cmp`` to compare the elements. The expected
## return values are the same as that of ``system.cmp``.
@ -763,7 +763,7 @@ proc rotateLeft*[T](arg: var openArray[T]; slice: HSlice[int, int];
##
## Elements outside of ``slice`` will be left unchanged.
## The time complexity is linear to ``slice.b - slice.a + 1``.
## If an invalid range (``HSlice``) is passed, it raises IndexError.
## If an invalid range (``HSlice``) is passed, it raises IndexDefect.
##
## ``slice``
## The indices of the element range that should be rotated.
@ -783,7 +783,7 @@ proc rotateLeft*[T](arg: var openArray[T]; slice: HSlice[int, int];
assert a == [0, 3, 4, 1, 2, 5]
a.rotateLeft(1 .. 4, -3)
assert a == [0, 4, 1, 2, 3, 5]
doAssertRaises(IndexError, a.rotateLeft(1 .. 7, 2))
doAssertRaises(IndexDefect, a.rotateLeft(1 .. 7, 2))
let sliceLen = slice.b + 1 - slice.a
let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen
arg.rotateInternal(slice.a, slice.a+distLeft, slice.b + 1)
@ -813,7 +813,7 @@ proc rotatedLeft*[T](arg: openArray[T]; slice: HSlice[int, int],
## not modify the argument. It creates a new ``seq`` instead.
##
## Elements outside of ``slice`` will be left unchanged.
## If an invalid range (``HSlice``) is passed, it raises IndexError.
## If an invalid range (``HSlice``) is passed, it raises IndexDefect.
##
## ``slice``
## The indices of the element range that should be rotated.

View file

@ -31,7 +31,7 @@ template createCb(retFutureSym, iteratorNameSym,
if not retFutUnown.finished:
let msg = "Async procedure ($1) yielded `nil`, are you await'ing a " &
"`nil` Future?"
raise newException(AssertionError, msg % strName)
raise newException(AssertionDefect, msg % strName)
else:
{.gcsafe.}:
{.push hint[ConvFromXtoItselfNotNeeded]: off.}
@ -260,7 +260,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
template await(f: typed): untyped =
static:
error "await expects Future[T], got " & $typeof(f)
template await[T](f: Future[T]): auto =
var internalTmpFuture: FutureBase = f
yield internalTmpFuture

View file

@ -12,7 +12,7 @@
##
## None of the procs that get an individual value from the deque can be used
## on an empty deque.
## If compiled with `boundChecks` option, those procs will raise an `IndexError`
## If compiled with `boundChecks` option, those procs will raise an `IndexDefect`
## on such access. This should not be relied upon, as `-d:release` will
## disable those checks and may return garbage or crash the program.
##
@ -24,7 +24,7 @@
##
## var a = initDeque[int]()
##
## doAssertRaises(IndexError, echo a[0])
## doAssertRaises(IndexDefect, echo a[0])
##
## for i in 1 .. 5:
## a.addLast(10*i)
@ -70,7 +70,7 @@ template initImpl(result: typed, initialSize: int) =
assert isPowerOfTwo(initialSize)
result.mask = initialSize-1
newSeq(result.data, initialSize)
template checkIfInitialized(deq: typed) =
when compiles(defaultInitialSize):
if deq.mask == 0:
@ -97,16 +97,16 @@ template emptyCheck(deq) =
# Bounds check for the regular deque access.
when compileOption("boundChecks"):
if unlikely(deq.count < 1):
raise newException(IndexError, "Empty deque.")
raise newException(IndexDefect, "Empty deque.")
template xBoundsCheck(deq, i) =
# Bounds check for the array like accesses.
when compileOption("boundChecks"): # d:release should disable this.
if unlikely(i >= deq.count): # x < deq.low is taken care by the Natural parameter
raise newException(IndexError,
raise newException(IndexDefect,
"Out of bounds: " & $i & " > " & $(deq.count - 1))
if unlikely(i < 0): # when used with BackwardsIndex
raise newException(IndexError,
raise newException(IndexDefect,
"Out of bounds: " & $i & " < 0")
proc `[]`*[T](deq: Deque[T], i: Natural): T {.inline.} =
@ -117,7 +117,7 @@ proc `[]`*[T](deq: Deque[T], i: Natural): T {.inline.} =
a.addLast(10*i)
assert a[0] == 10
assert a[3] == 40
doAssertRaises(IndexError, echo a[8])
doAssertRaises(IndexDefect, echo a[8])
xBoundsCheck(deq, i)
return deq.data[(deq.head + i) and deq.mask]
@ -131,7 +131,7 @@ proc `[]`*[T](deq: var Deque[T], i: Natural): var T {.inline.} =
a.addLast(10*i)
assert a[0] == 10
assert a[3] == 40
doAssertRaises(IndexError, echo a[8])
doAssertRaises(IndexDefect, echo a[8])
xBoundsCheck(deq, i)
return deq.data[(deq.head + i) and deq.mask]
@ -160,7 +160,7 @@ proc `[]`*[T](deq: Deque[T], i: BackwardsIndex): T {.inline.} =
a.addLast(10*i)
assert a[^1] == 50
assert a[^4] == 20
doAssertRaises(IndexError, echo a[^9])
doAssertRaises(IndexDefect, echo a[^9])
xBoundsCheck(deq, deq.len - int(i))
return deq[deq.len - int(i)]
@ -175,7 +175,7 @@ proc `[]`*[T](deq: var Deque[T], i: BackwardsIndex): var T {.inline.} =
a.addLast(10*i)
assert a[^1] == 50
assert a[^4] == 20
doAssertRaises(IndexError, echo a[^9])
doAssertRaises(IndexDefect, echo a[^9])
xBoundsCheck(deq, deq.len - int(i))
return deq[deq.len - int(i)]
@ -569,14 +569,14 @@ when isMainModule:
try:
echo deq[99]
assert false
except IndexError:
except IndexDefect:
discard
try:
assert deq.len == 4
for i in 0 ..< 5: deq.popFirst()
assert false
except IndexError:
except IndexDefect:
discard
# grabs some types of resize error.

View file

@ -26,11 +26,11 @@
##
## .. code-block:: Nim
## import asyncdispatch, httpclient
##
##
## proc asyncProc(): Future[string] {.async.} =
## var client = newAsyncHttpClient()
## return await client.getContent("http://example.com")
##
##
## echo waitFor asyncProc()
##
## The functionality implemented by ``HttpClient`` and ``AsyncHttpClient``
@ -225,7 +225,7 @@ type
bodyStream*: FutureStream[string]
proc code*(response: Response | AsyncResponse): HttpCode
{.raises: [ValueError, OverflowError].} =
{.raises: [ValueError, OverflowDefect].} =
## Retrieves the specified response's ``HttpCode``.
##
## Raises a ``ValueError`` if the response's ``status`` does not have a

View file

@ -1300,18 +1300,18 @@ when isMainModule:
when compileOption("boundChecks"):
try:
let a = testJson["a"][9]
doAssert(false, "IndexError not thrown")
except IndexError:
doAssert(false, "IndexDefect not thrown")
except IndexDefect:
discard
try:
let a = testJson["a"][-1]
doAssert(false, "IndexError not thrown")
except IndexError:
doAssert(false, "IndexDefect not thrown")
except IndexDefect:
discard
try:
doAssert(testJson["a"][0].num == 1, "Index doesn't correspond to its value")
except:
doAssert(false, "IndexError thrown for valid index")
doAssert(false, "IndexDefect thrown for valid index")
doAssert(testJson{"b"}.getStr() == "asd", "Couldn't fetch a singly nested key with {}")
doAssert(isNil(testJson{"nonexistent"}), "Non-existent keys should return nil")
@ -1378,7 +1378,7 @@ when isMainModule:
try:
discard parsed["key2"][12123]
doAssert(false)
except IndexError: doAssert(true)
except IndexDefect: doAssert(true)
var parsed2 = parseFile("tests/testdata/jsontest2.json")
doAssert(parsed2{"repository", "description"}.str ==

View file

@ -1205,7 +1205,7 @@ when isMainModule:
block: # fac() tests
try:
discard fac(-1)
except AssertionError:
except AssertionDefect:
discard
doAssert fac(0) == 1

View file

@ -457,7 +457,7 @@ proc fromSockAddrAux(sa: ptr Sockaddr_storage, sl: SockLen,
proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6,
sl: SockLen, address: var IpAddress, port: var Port) {.inline.} =
## Converts `SockAddr` and `SockLen` to `IpAddress` and `Port`. Raises
## `ObjectConversionError` in case of invalid `sa` and `sl` arguments.
## `ObjectConversionDefect` in case of invalid `sa` and `sl` arguments.
fromSockAddrAux(cast[ptr Sockaddr_storage](unsafeAddr sa), sl, address, port)
when defineSsl:
@ -488,7 +488,7 @@ when defineSsl:
proc getExtraData*(ctx: SslContext, index: int): RootRef =
## Retrieves arbitrary data stored inside SslContext.
if index notin ctx.referencedData:
raise newException(IndexError, "No data with that index.")
raise newException(IndexDefect, "No data with that index.")
let res = ctx.context.SSL_CTX_get_ex_data(index.cint)
if cast[int](res) == 0:
raiseSSLError()

View file

@ -74,8 +74,8 @@ type
val: T
has: bool
UnpackError* = object of Defect
UnpackDefect* = object of Defect
UnpackError* {.deprecated: "See corresponding Defect".} = UnpackDefect
proc option*[T](val: T): Option[T] =
## Can be used to convert a pointer type (`ptr` or `ref` or `proc`) to an option type.
@ -486,7 +486,7 @@ when isMainModule:
let tmp = option(intref)
check(sizeof(tmp) == sizeof(ptr int))
var prc = proc (x: int): int = x + 1
check(option(prc).isSome)
prc = nil

View file

@ -2678,7 +2678,7 @@ when defined(nimdoc):
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
## Returns the `i`-th `command line argument`:idx: given to the application.
##
## `i` should be in the range `1..paramCount()`, the `IndexError`
## `i` should be in the range `1..paramCount()`, the `IndexDefect`
## exception will be raised for invalid values. Instead of iterating over
## `paramCount() <#paramCount>`_ with this proc you can call the
## convenience `commandLineParams() <#commandLineParams>`_.
@ -2754,7 +2754,7 @@ elif defined(windows):
ownArgv = parseCmdLine($getCommandLine())
ownParsedArgv = true
if i < ownArgv.len and i >= 0: return TaintedString(ownArgv[i])
raise newException(IndexError, formatErrorIndexBound(i, ownArgv.len-1))
raise newException(IndexDefect, formatErrorIndexBound(i, ownArgv.len-1))
elif defined(genode):
proc paramStr*(i: int): TaintedString =
@ -2773,7 +2773,7 @@ elif not defined(createNimRtl) and
proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} =
# Docstring in nimdoc block.
if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
raise newException(IndexError, formatErrorIndexBound(i, cmdCount-1))
raise newException(IndexDefect, formatErrorIndexBound(i, cmdCount-1))
proc paramCount*(): int {.tags: [ReadIOEffect].} =
# Docstring in nimdoc block.

View file

@ -393,7 +393,7 @@ proc captureBetween*(s: string, first: char, second = '\0', start = 0): string =
result = ""
discard s.parseUntil(result, if second == '\0': first else: second, i)
proc integerOutOfRangeError() {.noinline.} =
proc integerOutOfRangeDefect() {.noinline.} =
raise newException(ValueError, "Parsed integer outside of valid range")
# See #6752
@ -416,11 +416,11 @@ proc rawParseInt(s: string, b: var BiggestInt, start = 0): int =
if b >= (low(BiggestInt) + c) div 10:
b = b * 10 - c
else:
integerOutOfRangeError()
integerOutOfRangeDefect()
inc(i)
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
if sign == -1 and b == low(BiggestInt):
integerOutOfRangeError()
integerOutOfRangeDefect()
else:
b = b * sign
result = i - start
@ -459,7 +459,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
result = parseBiggestInt(s, res, start)
when sizeof(int) <= 4:
if res < low(int) or res > high(int):
integerOutOfRangeError()
integerOutOfRangeDefect()
if result != 0:
number = int(res)
@ -493,7 +493,7 @@ proc rawParseUInt(s: string, b: var BiggestUInt, start = 0): int =
prev = 0.BiggestUInt
i = start
if i < s.len - 1 and s[i] == '-' and s[i + 1] in {'0'..'9'}:
integerOutOfRangeError()
integerOutOfRangeDefect()
if i < s.len and s[i] == '+': inc(i) # Allow
if i < s.len and s[i] in {'0'..'9'}:
b = 0
@ -501,7 +501,7 @@ proc rawParseUInt(s: string, b: var BiggestUInt, start = 0): int =
prev = res
res = res * 10 + (ord(s[i]) - ord('0')).BiggestUInt
if prev > res:
integerOutOfRangeError()
integerOutOfRangeDefect()
inc(i)
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
b = res
@ -540,7 +540,7 @@ proc parseUInt*(s: string, number: var uint, start = 0): int {.
result = parseBiggestUInt(s, res, start)
when sizeof(BiggestUInt) > sizeof(uint) and sizeof(uint) <= 4:
if res > 0xFFFF_FFFF'u64:
integerOutOfRangeError()
integerOutOfRangeDefect()
if result != 0:
number = uint(res)

View file

@ -676,13 +676,13 @@ when isMainModule:
try:
discard rand(-1)
doAssert false
except RangeError:
except RangeDefect:
discard
try:
discard rand(-1.0)
doAssert false
except RangeError:
except RangeDefect:
discard

View file

@ -93,7 +93,7 @@ proc reduce*[T: SomeInteger](x: var Rational[T]) =
x.num = -x.num div common
x.den = -x.den div common
else:
raise newException(DivByZeroError, "division by zero")
raise newException(DivByZeroDefect, "division by zero")
proc `+` *[T](x, y: Rational[T]): Rational[T] =
## Add two rational numbers.
@ -194,7 +194,7 @@ proc reciprocal*[T](x: Rational[T]): Rational[T] =
result.num = -x.den
result.den = -x.num
else:
raise newException(DivByZeroError, "division by zero")
raise newException(DivByZeroDefect, "division by zero")
proc `/`*[T](x, y: Rational[T]): Rational[T] =
## Divide rationals `x` by `y`.

View file

@ -8,17 +8,17 @@
#
## This modules registers a signal handler that turns access violations /
## segfaults into a ``NilAccessError`` exception. To be able to catch
## a NilAccessError all you have to do is to import this module.
## segfaults into a ``NilAccessDefect`` exception. To be able to catch
## a NilAccessDefect all you have to do is to import this module.
##
## Tested on these OSes: Linux, Windows, OSX
{.used.}
# do allocate memory upfront:
var se: ref NilAccessError
var se: ref NilAccessDefect
new(se)
se.name = "NilAccessError"
se.name = "NilAccessDefect"
se.msg = "Could not access value because it is nil."
when defined(windows):

View file

@ -88,7 +88,7 @@
##
## test "out of bounds error is thrown on bad access":
## let v = @[1, 2, 3] # you can do initialization here
## expect(IndexError):
## expect(IndexDefect):
## discard v[4]
##
## echo "suite teardown: run once after the tests"
@ -190,7 +190,7 @@ proc delOutputFormatter*(formatter: OutputFormatter) =
proc resetOutputFormatters* {.since: (1, 1).} =
formatters = @[]
proc newConsoleOutputFormatter*(outputLevel: OutputLevel = OutputLevel.PRINT_ALL,
colorOutput = true): <//>ConsoleOutputFormatter =
ConsoleOutputFormatter(
@ -717,7 +717,7 @@ macro expect*(exceptions: varargs[typed], body: untyped): untyped =
## of 3: raise newException(IOError, "I can't do that Dave.")
## else: assert 2 + 2 == 5
##
## expect IOError, OSError, ValueError, AssertionError:
## expect IOError, OSError, ValueError, AssertionDefect:
## defectiveRobot()
let exp = callsite()
template expectBody(errorTypes, lineInfoLit, body): NimNode {.dirty.} =