Sheerpower Logo

Exception Handling


Exception handling routines intercept runtime exceptions and execute a block of code which handles them. If there is no exception handler, Sheerpower returns an exception message specifying what the exception was and where it occurred. Sheerpower stops program execution or tries the offending statement again.

There are two types of exception handlers: ATTACHED handlers and DETACHED handlers. Attached handlers are the most commonly used handlers. They are similar to the try/catch blocks that other languages provide.

For an ATTACHED handler, a WHEN EXCEPTION IN statement is used. WHEN EXCEPTION IN expects the USE block right after the block of code it protects.

For a DETACHED handler, the statement WHEN EXCEPTION USE is used. When an exception occurs in the protected block, WHEN EXCEPTION USE calls a handler routine located in some other part of the program. The same handler routine can be used by any number of WHEN EXCEPTION USE statements and can be placed anywhere in a program.

The following functions are related to exception handling:
  • _ERROR — Set to TRUE if there was an exception error.
  • EXTYPE — The exception type number.
  • EXLABEL$ — The location in the code where the exception occurred.
  • EXTEXT$ — A user-friendly description of the exception.
  • SYSTEXT$ — The underlying operating system’s description of the exception (if any).
  • EXCEPTIONTYPE — Given an exception name (case-insensitive), returns the exception type number. If an unknown exception name literal is given, a compile-time error is posted -- Unknown exception name. Any casing works: "DIVBY0", "divby0", and "DivBy0" are all equivalent.
  • EXCEPTIONNAME$ — Given an EXTYPE, returns the exception name. Returns a null string if there is no matching exception name.

// With a string literal, ExceptionType("divby0") folds to 3001 at compile time (zero-cost) // An unknown exception name literal will cause a compile time error of Unknown exception name. if extype = exceptiontype("divby0") then ... ... end if

Handling Multiple Exception Types

When handling multiple exception types, SELECT CASE provides a clean and readable way to check which exception occurred. Instead of chaining multiple IF / ELSE IF statements, you can use SELECT CASE with the EXTYPE function to handle different exceptions appropriately.

Basic Exception Handling with SELECT CASE

sheerpower when exception in // Code that might cause exceptions x = 10 / y open #1: name filename$ use select case extype case exceptiontype("divby0") print "Error: Division by zero!" y = 1 retry case exceptiontype("filenotfound") print "Error: File not found - "; extext$ continue case exceptiontype("accessdenied") print "Error: Access denied to file" continue case else print "Unexpected error: "; extext$ print "Location: "; exlabel$ continue end select end when

Multiple Exception Types Per CASE

You can handle similar exceptions together by listing multiple exception types in a single CASE statement.

sheerpower when exception in // File operations open #1: name filename$, access input input #1: data$ use select case extype case exceptiontype("filenotfound"), exceptiontype("pathnotfound") print "Error: Cannot locate "; filename$ continue case exceptiontype("accessdenied"), exceptiontype("sharingviolation") print "Error: Cannot access file - permission or sharing issue" continue case exceptiontype("endoffile") print "Reached end of file" continue case else print "File error: "; extext$ continue end select end when

Using CASE IS with Exception Ranges

Some exceptions fall into numeric ranges. You can use CASE IS to handle them efficiently.

sheerpower when exception in // Code that might fail perform_operation() use select case extype case is < 2000 print "System-level error: "; systext$ continue case 3000 to 3999 print "Arithmetic error: "; extext$ retry case is >= 5000 print "User-defined error: "; extext$ continue case else print "Other error: "; extext$ continue end select end when
And the following statements are related to exception handling:
  • CONTINUE -- continue execution with the statement that follows the statement that caused the exception
  • RETRY -- retry the statement that caused the exception
  • CAUSE EXCEPTION -- given an exception type number, cause an exception

Call-Depth Snapshot & Safe Rollback

When execution enters a WHEN EXCEPTION block (both ATTACHED and DETACHED), Sheerpower snapshots the current routine call depth. If an exception occurs anywhere inside the protected region, the runtime rewinds all routine calls to that saved depth before transferring control to the handler. Because Sheerpower uses a stackless calling model (no traditional call stack), this rewind is extremely fast.

routine do_b // Raises DIVBY0 if y = 0 x = 10 / y print "do_b finished" // not reached if exception occurs end routine routine do_a print "in do_a" do_b print "leaving do_a" // skipped when exception in do_b end routine y = 0 // force a divide by zero in routine do_b when exception in do_a // nested calls under protection use if extype = exceptiontype("divby0") then print "Handler: fixing y and retrying..." y = 1 retry // re-executes the failing statement in do_b -- (10 / y) else print "Unexpected: "; extext$ continue end if end when print "after protected block"

  • Rollback boundary: On entering WHEN EXCEPTION ... USE, Sheerpower snapshots the protected region’s routine depth. If an exception occurs, all deeper routine calls are discarded (later restored for RETRY/CONTINUE) before the USE handler runs.
  • RETRY: Restores the saved routine depth and re-executes the original failing statement -- usually after adjusting the values that caused the exception.
  • CONTINUE: Restores the saved routine depth and resumes with the first statement after the one that failed.
  • Why it’s fast: No call stack to unwind—Sheerpower resets to the saved routine depth and transfers control with virtually instant rewind.
Problem: Deep, nested calls fail and leave partial state.

Solution: The handler snapshots call depth on entry and rewinds to that depth on exception, then runs with a clean routine-depth boundary.

Efficiency: Stackless rewind is virtually instant; no cleanup code in each nested routine.

Takeaway: Wrap risky regions with WHEN EXCEPTION; use RETRY for targeted fixes or CONTINUE to move on, skipping the failing statement.

Unhandled Exceptions and Bubble-Up Behavior

If an exception occurs and no matching WHEN EXCEPTION handler is present in the current block, Sheerpower automatically bubbles up the exception to the next higher-level handler in the call stack. This means the system searches for a broader handler in the calling routine or main program. If no handler is found anywhere, the program stops and displays an exception message describing the error, its type, and the source location (via EXLABEL$ and EXTEXT$).

Problem: A lower-level routine fails without its own WHEN EXCEPTION block.

Solution: Sheerpower passes the exception upward (“bubble-up”) until a higher-level routine handles it.

Efficiency: This avoids repetitive handlers and lets you centralize recovery logic in one place.

Takeaway: In general, place at least one global WHEN EXCEPTION block near the top level of your program to ensure all unexpected errors are caught gracefully.

CAUSE EXCEPTION

The CAUSE EXCEPTION statement lets you generate an exception deliberately when specific conditions occur. This is useful for enforcing input validation, custom error logic, or consistent error signaling between routines.

Format

CAUSE EXCEPTION exception_number
  

Example

sheerpower do input "Select a number between 1 and 10": no if no < 1 or no > 10 then cause exception 1001 repeat do end do end

Example output:

Select a number between 1 and 10? 8 Select a number between 1 and 10? 99 Illegal number at 10.2

Description

CAUSE EXCEPTION forces the specified exception number to occur as though the runtime system had generated it. The exception_number may be any integer expression. When executed, Sheerpower immediately raises that exception, invoking any active WHEN EXCEPTION handler or bubbling upward until a handler is found.

Problem: You need to trigger controlled exceptions for invalid inputs or business rules.

Solution: Use CAUSE EXCEPTION with a specific number that your handler recognizes.

Efficiency: Allows consistent error reporting without complex condition checks spread across code.

Takeaway: Use CAUSE EXCEPTION to enforce program rules and simplify validation logic.
(Show/Hide Sheerpower Exception Type Table)
Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.