<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Parrot - Exceptions</title> <link rel="stylesheet" type="text/css" href="../../../../resources/parrot.css" media="all"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="wrapper"> <div id="header"> <a href="http://www.parrot.org"> <img border=0 src="../../../../resources/parrot_logo.png" id="logo" alt="parrot"> </a> </div> <!-- "header" --> <div id="divider"></div> <div id="mainbody"> <div id="breadcrumb"> <a href="../../../../html/index.html">Home</a> » <a href="../../../../html/developer.html">Developer Documentation</a> » Exceptions </div> <h1><a name="Exceptions" >Exceptions</a></h1> <p>This is a basic overview of how to deal with exceptions from PIR. There are two main topics: throwing exceptions and catching exceptions. We'll start with the first.</p> <h2><a name="Throwing_exceptions" >Throwing exceptions</a></h2> <p>If you're going to be using exceptions, you probably want to start by including two pasm files that define constants for exception type and severity.</p> <p>You create exceptions just like you create any other object, with <code>new</code>.</p> <p>You usually want to at least set a descriptive message about what went wrong.</p> <p>You also usually want to set a severity and sometimes a type. You can find these in <a href='TODO#parrot%2Finclude%2Fexcept_severity.pasm'>"parrot/include/except_severity.pasm" in runtime</a>.</p> <p>You actually throw the exception by using the <code>throw</code> op.</p> <p>Put all together, it looks like this:</p> <pre> .include 'except_types.pasm' .include 'except_severity.pasm' .local pmc ex ex = new 'Exception' ex = "Everything is horrible, dood." ex['severity'] = .EXCEPT_DOOMED ex['type'] = .CONTROL_ERROR throw ex </pre> <h2><a name="Catching_exceptions" >Catching exceptions</a></h2> <p>Parrot maintains a stack of exception handlers. When an exception is thrown, Parrot iterates through the stack looking for a handler that can handle the exception. When it finds a valid exception handler, the exception handler is invoked with the exception as an argument. Exception handlers run in the context of the <code>throw</code> that they're handling.</p> <p>You create exception handlers just like you create any other object, with <code>new</code>.</p> <pre> .local pmc eh eh = new 'ExceptionHandler' </pre> <p>You set the target of the exception handler (the code that will be invoked) with the <code>set_attr</code> opcode. Usually this will be a label. You manipulate the exception handler stack with the <code>push_eh</code> and <code>pop_eh</code> opcodes. This is a fairly standard use of exception handlers:</p> <pre> .local pmc eh eh = new 'ExceptionHandler' set_addr eh, handler push_eh eh # code that might throw an exception pop_eh .return (1) # Success! handler: .local pmc ex .get_results (ex) # code that prints a warning, logs an error, whatever .return (0) # Failure! </pre> <p>Sometimes you want to be more specific in what you catch. You can set filters on the exception handler based on exception type and severity. The methods you use include <code>.min_severity()</code>, <code>.max_severity()</code>, <code>.handle_types()</code>, and <code>.handle_types_except()</code>.</p> <p>Here's an example of a sub that catches only error exceptions and prints an appropriate log message before exiting.</p> <pre> .include 'except_severity.pasm' .sub 'dostuff' .local pmc eh eh = new 'ExceptionHandler' set_addr eh, handler eh.'min_severity'(.EXCEPT_ERROR) push_eh eh # ... stuff that might throw an error pop_eh .return (1) handler: .local pmc ex .local string msg .get_results (ex) print "There was a fatal error in dostuff: " msg = ex say ex exit 1 .end </pre> </div> <!-- "mainbody" --> <div id="divider"></div> <div id="footer"> Copyright © 2002-2011, Parrot Foundation. </div> </div> <!-- "wrapper" --> </body> </html>