DEV Community

Manav
Manav

Posted on • Edited on

Learning Nim: Exception Handling - I

I began exploring about it in Nim's manual and loved the concept of effect systems. I'll probably do one more post about it in the future.

# What's Refreshing: No divide by zero error
var a = 0
echo -89/a #-Inf
echo NegInf > Inf #false

Usual Try, Except, Finally

from strutils import parseInt

try:
    var x = parseInt("133a")

except ValueError as e:
    echo "We made an error: ", e.msg #We made an error: invalid integer: 133a

    #For when we don't use 'as e'
    var error = getCurrentException() 
    echo error.msg #invalid integer: 133a

    #If we're in a hurry
    echo getCurrentExceptionMsg() #invalid integer: 133a

finally:
    echo "I will get executed regardless of an error" 

Custom Exceptions

type MyException* = object of Exception
if(1 == 1):
    raise MyException.newException("This Exception is mine!! Get your own!")
    #OR raise newException(MyException, "This Exception is mine!! Get your own!")

The * is there so that MyException is visible to other modules too.

But can we raise predefined errors with custom messages?

raise newException(IOError, "This is IO speaking, Er Yes you can!")

Try Expression

from strutils import parseInt
let x = try: parseInt("133a")
        except: -1
        finally: echo "hi"

echo x

try except and finally(optional) works as they do, and you get to dynamically decide the value of x in a single expression. But you cannot use multi-line code inside the try-except block. You can, in finally block.

Note: There are also defer statement which I haven't covered here

Exception Tracking

Who knew you can explicitly define what exceptions your proc/iterator/method/converter can raise!

proc p(what: bool) {.raises: [IOError, OSError].} =
  if what: 
    raise newException(ValueError, "It won't compile") #ERROR

p(true) 

The compiler won't let you raise any error that's not defined.

What if we try a custom exception?

type MyException = object of ValueError
proc p(what: bool) {.raises: [IOError, OSError].} =
  if what: 
    raise newException(MyException, "Still won't compile") #ERROR

p(true) 

What if my custom exception was generic type?

type MyException = object of Exception

proc p(what: bool) {.raises: [IOError, OSError].} =
  if what: 
    raise newException(MyException, "Still won't compile") #ERROR

p(true)

What if I design the code to throw an undefined error?

from strutils import parseInt

proc p(what: bool) {.raises: [IOError, OSError].} =

  var a = parseInt("133a") #Throws ValueError usually
  echo a

p(true) #Still doesn't work

That's it. I need more experience with it to completely understand the effect system and then I'll be back with part II post.

If you learnt something from this post, hit ❤️ and share! Others deserve to know about it too!

Top comments (0)