exception handling, debugging, documentation
TLDR
- docgen:
- having * after - (like on this line) will break htmldocs rst parser
- you must escape it with backticks * or backslash *
- error reported as Error: '*' expected
- pretty prints code in the html
- back ticks and back slashes e.g. *.nims can escape special chars
- if reusing rsts (e.g. for github readmes)
- make sure to add an empty line before the first indented list item
- IMO always externalize readme.rst files so their viewable in github & in html docs
- having * after - (like on this line) will break htmldocs rst parser
- exceptions
- all custom exceptions should ref a specific error/CatchableERror/Defect/and lastly Exception
- Exception is the base type for CatachableError (exceptions) and Defect (non catchable)
- has to be allocated on the heap (requires ref) because their lifetime is unknown
- raise keyword for throwing an exception/defect
- causes execution to cease until caught or program exits
- e.g. raise errInstance
- e.g. raise newException(OSError, "Oops! did i do that?")
- raising without an error rethrows the previous exception
- compile with --panics:on to make defects unrecoverable
- tracebacks:
- each line in the stack track is a call to a procedure
- all custom exceptions should ref a specific error/CatchableERror/Defect/and lastly Exception
- assert
- -d:danger or --asertions:off to remove from compilation
- --assertions:on to keep them in compiled output
- doAssert
- always on regardless of flags
- can be used to check for specific errors with doAssertRaises(woop): block
- useful for hard checks & design by contract
- drnim
- requires koch to be setup
links
- other
- devel source
- high impact
- niche
TODOs
- drnim tool
- debugger
- try-except discussion
errorMessageWriter (var) called instead of stdmsg.write when printing stacktrace onUnhandledException (var) override default behavior: write stacktrace to stderr then quit(1) outOfMemHook (var) override default behavior: write err msg then terminate (see docs for example) unhandledExceptionHook (var) override default behavior: write err msg then terminate localRaiseHook: same as globalRaiseHook but on a thread local level globalRaiseHook (var) influence exception handling on a global level ^ if not nil, every raise statement calls this hook ^ if returns false, exception is caught and does not propagate
Exception Handling
- interesting stuff
- getStackTrace() only works for debug builds
- getStackTrace(e) of a specific exception
- getStackTraceEntries() doesnt work for the js backend
Defect types
- AccessViolationDefect invalid memory access
- ArithmeticDefect any kin dof arithmetic error
- AssertionDefect assertion returns false
- DeadThreadDefect sending a msg to a dead thread
- Defect abstract type representing all uncatchable errors (anything mappable to a quit/trap/exit operation)
- DivByZeroDefect int div by 0
- FieldDefect field is not accessible because its discriminants value does not fit
- FloatDivByZeroDefect float div by 0
- FloatInexactDefect operation cant be represented with infinite precision, e.g. 2.0/3.0, log(1.1)
- FloatingPointDefect base type for floating point defects
- FloatInvalidOpDefect invalid ops according to IEEE, e.g. 0.0/0.0
- FloatOverflowDefect stackoverflow.com
- FloatUnderflowDefect stackunderflow.com
- IndexDefect array index out of bounds
- NilAccessDefect dereferences of nil pointers (only raised when segfaults is imported)
- ObjectAssignmentDefect object being assigned to its parent object
- ObjectConversionDefect converting to an incompatible type
- OutOfMemDefect failed to allocate memory
- OverflowDefect runtime integer stackoverflows.com, results too big for the provided bits
- RangeDefect range check error
- ReraiseDefect if there is no exception to reraise
- StackOverflowDefect when the hardware used for a subroutine stackoverflows.com
Error (exception) types
- CatchableError abstract type for all catchable exceptions
- EOFError occurred
- IOError occcurred
- KeyError key cannot be found in a table/set/strtabs
- LibraryError dynamic library doesnt load
- OSError operating system service failure
- ResourceExhaustedError when resource request cant be fulfilled
- ValueError string/object conversion
try/except/finally
- like most things can be an expression and assigned to a var
- the try + except must all be of the same type
- if theres a finally, it must return void
defer
- alternative try finally statement that avoids lexical nesting + scoping flexibility
- all statements after defer will be within an implicit try block
- top level defers arent supported (must be within a block/proc/etc)
assert
- useful for guard, pre & post conditions if using design by contract
- i think drnim even extends this further
documentation
- starting a line with ## creates a title that appears in the left sidebar
- both --- and === need to be the same length of whatever they're underlining
- === creates an underline
- --- creates a subtitle and appears undearneath the previous title in the sidebar
- low(openArray) creates an html #fragment ?
- starting a line with .. code-block:: Nim creates a codeblock for stuff indented beneath it
- starting a line with .. image:: woopwoop.com/image.gif creates an image
- include another doc file .. include:: ./system_overview.rst
- .. _LinkName: some.url.com can be referenced as LinkName_
runnableExamples
- example code to be formatted and displayed in html docs
- ignored in release/debug, but parsed during docgen:
- will aggregate all into a separate module, compile, test
- ensures only exported symbols exist
- errors if private symbols are included
Example:
import src/bookofnim/helloworld/modules/exceptionHandlingDocs var iam = GoodApplications(pubfield: "yes u are", prvfield: "I know I am") ## \ ## example of creating a good application discard repr iam
Types
GoodApplications = object pubfield*: string ## public: included in docs prvfield*: string
- especially things like custom types may need additional abbreviations to describe their purpose Source Edit
Procs
proc deferExample(): auto {....raises: [], tags: [], forbids: [].}
- Source Edit
proc maybeThrows(x: int): int {....raises: [ValueError], tags: [], forbids: [].}
- only value errors are allowed Source Edit
proc neverThrows(): string {....raises: [], tags: [], forbids: [].}
- we set raises to empty list Source Edit
Templates
template raisedForeign`gensym12() {.gensym.}
- Source Edit