Exception Handling

During structure processing or content processing, various exception conditions may arise. This clause defines the set of exceptions that may arise, and the exception handling mechanisms of the SPDL presentation process. Exception handling provides a way to continue processing at some relevant point either avoiding the action that caused the exception or mitigating its effects.

Exceptions are defined and handled at two levels. Structure exceptions arise and are handled at the BLOCK level. The exceptions that may arise in structure are defined in . Structure exception handling is defined in . Content exceptions arise at the content level. The exceptions that may arise are defined in . Content exception handling is defined in . Operators having to do with content exceptions and content exception handling are defined in . Interpreter errors form a special class of exception conditions that may arise in content. These are defined in .

Structure Exceptions

A structure exception arises within a BLOCK, upon any of the following occurrances:

When any of the above violations occur, an exception is raised in the BLOCK most immediately superior to the structure in which the violation occurs.

Syntax error in structure

A syntax error arises in a BLOCK when the structure processor encounters structures or parts thereof, subordinate to the BLOCK, which violate the syntax prescribed in and of this International Standard.

Illegal specification in structure

An illegal specification exception arises in a BLOCK when the structure processor encounters structure elements, subordinate to the BLOCK, which specify a value or values which are not allowed by this International Standard.

Implementation constraint violation

An implementation constraint violation arises in a BLOCK when the structure processor encounters structure elements, subordinate to the BLOCK, which specify values which are not supported by the implementation. In a conforming implementation, this exception can only arise in regard to specific limits as defined in this International Standard; see .

Unhandled content exception in content

An unhandled content exception arises in a BLOCK when the Content Processor encounters an unhandled content exception in content subordinate to the BLOCK. (See and for content exceptions and content exception handling.)

Unhandled structure exception in subordinate BLOCK

When any of the above five structure exceptions occur in a BLOCK, if that BLOCK does not handle the exception (see ), then the same structure exception arises in the most immediately superior BLOCK.

If an unhandled structure exception occurs in the DOCUMENT (to which there is no superior BLOCK) then the exception is handled as specified in .

Structure Exception Handling

The Block State of each BLOCK has an abort-policy presentation parameter, which may have values of dpi::abort-policy::on-warning, dpi::abort-policy::on-error, or dpi::abort-policy::struggle-on (see ).

If a structure warning occurs in a BLOCK whose abort-policy presentation parameter has a value of dpi::abort-policy::on-error, it typically does not cause a structure exception to occur. Instead, it causes a warning message to be issued to the print requestor in an implementation-dependent way.

If a structure warning occurs in a BLOCK whose abort-policy presentation parameter has a value of dpi::abort-policy::on-warning, a structure exception is raised in addition to a warning message being sent to the print requestor.

The following subclauses describe the handling of structure exceptions.

dpi::abort-policy::struggle-on

If a structure exception is raised in a BLOCK for which the abort-policy presentation parameter value is dpi::abort-policy::struggle-on, then the exception is said to be handled. An implemetation dependent warning message to the print requestor may be issued. This warning message might be transmitted to the process that invoked the SPDL process by a reverse channel whose structure and protocols are not defined by this International Standard, or it might be printed on a break page or banner page.

No further processing of the content or structures subordinate to the BLOCK is performed by the presentation process. However, if the BLOCK in which the exception occurs is a PAGE, then the PAGE shall be presented. The page image presented on this page shall be implementation dependent.

Structure processing resumes with the structure immediately following the BLOCK in which the exception occurred. If the exception occurs in a BLOCK subordinate to a PAGE, the cumulative state of the resultant Current Page Image shall be implementation-dependent. It is recommended that the resultant Current Page Image be as good a representation as possible of the result of the presentation process had the cause of the exception not been present in the document.

dpi::abort-policy::on-error, dpi::abort-policy::on-warning

If a structure exception is raised in a BLOCK for which the abort-policy presentation parameter value is dpi::abort-policy::on-error or dpi::abort-policy::on-warning, then the exception is said to be unhandled. An implemetation-dependent warning message to the print requestor may be issued. This warning message might be transmitted to the process that invoked the SPDL process by a reverse channel whose structure and protocols are not defined by this International Standard, or it might be printed on a break page or banner page.

No further processing of the content or structures subordinate to the BLOCK is performed by the presentation process. However, if the BLOCK in which the exception occurs is a PAGE, then the PAGE shall be presented. The page image presented on this page shall be implementation dependent. All pages preceding this page shall be correctly presented, as though the PAGE in which the exception arose had not been present.

When an unhandled exception occurs in a BLOCK, the same structure exception arises in the most immediately superior BLOCK. The effect of that structure exception in the most immediately superior BLOCK will depend on the value of the abort-policy presentation parameter in that BLOCK.

If an unhandled structure exception occurs in the DOCUMENT (to which there is no superior BLOCK) then processing of the document terminates. If the DOCUMENT is a single PAGE, then one page image shall be presented; the page image presented on this page shall be implementation dependent.

Content Exceptions

Content exceptions occur during content processing, as a result of executing any of the following operators: RaiseException, and (in some circumstances) RaiseError or RaiseWarning.

The execution of the RaiseException operator immediately causes a content exception to occur. This exception may be handled in content (see ) or not. If it is unhandled in content, then a structure exception will be caused. (see ).

The execution of the RaiseError operator does not itself cause a content exception to occur. Instead, it causes an error Procedure to be selected from the dictionary bound to the key ErrorDict in SystemDict, and the error Procedure is then executed. Error Procedures typically end by executing the RaiseException operator, thus causing a content exception to occur. (See for complete specification of error Procedures and their uses.) ErrorDict may be modified in content (see ). The error Procedure bound to a particular interpreter error name may be replaced, for example.

The execution of the RaiseWarning operator typically does not cause a content exception to occur. Instead, it causes a warning message to be issued to the print requestor in an implementation-dependent way. If, however,the Current Abort Policy component of the Virtual Machine has the value dpi::abort-policy::on-warning, then, after issuing the warning message, RaiseError shall be invoked with ContentWarning as its operand. This may raise an exception (see ).

Content Exception Handling

Content exceptions are the result of executing the RaiseException operator. Depending on the context of interpretation of this operator, the exception may be handled or unhandled. If the exception occurs during interpretation of a Procedure called by the ExecuteTrapped operator, then the exception will be handled. A Procedure invoked by the ExecuteTrapped operator is said to be executed in a trapped context. Otherwise, the exception will be unhandled.

Handled exceptions

The ExecuteTrapped operator provides a mechanism for executing a Procedure in a context in which content exceptions will be trapped. Upon occurrance of an exception, all execution of the Procedure and its subprocedures will halt, and content processing continues with the next object in normal sequence after the ExecuteTrapped operator. A boolean true is placed on the Operand Stack to show that an exception was trapped. (If the Procedure had been completely interpreted without an exception arising, a Boolean false would be placed on the Operand Stack.)

The Boolean returned by the ExecuteTrapped operator allows it to be followed by an exception handler Procedure, defined by the document, which can be conditionally executed if an exception occurs.

If an exception is trapped and handled in this way, the results are entirely under the control of the document.

Unhandled exceptions

If a content exception occurs in a context without exception trapping, then the content exception is unhandled. The Procedure ReportErrorInfo from ErrorDict is executed, and then a structure exception in the immediately superior BLOCK occurs.

Content Exception Operators and Procedures

The specification of these operators and their semantics includes the specification of conditions which may cause content exceptions to be raised as a result of interpretation of the operators. There is a class of generic errors some subset of which may be caused by each operator, which may lead to raising the corresponding generic exception. These generic errors and their semantics are described in . In addition, the individual operator specifications in through identify operator-specific errors that may lead to exceptions. These errors are also described in .

RaiseException

The RaiseException operator takes no arguments and returns no results. It terminates execution of the innermost dynamically enclosing instance of a trapped context, without regard to lexical relationship. The use of trapped contexts is discussed in , and the ExecuteTrapped operator itself in .If there is no such trapped context, then content processing is terminated and status returned to the structure processor shall be content-warning or content-error as appropriate. These two status values indicate an unhandled content exception.

RaiseError

The RaiseError operator takes one operand

  • <error: Name> and returns no results. The effect of executing the RaiseError operator is to execute the Procedure bound to error in ErrorDict.

    RaiseWarning

    The RaiseWarning operator takes one operand

  • <warning: OctetStringReference> and returns no results. The effect of executing the RaiseWarning operator is to execute the Print operator with warning as an operand, and then conditionally invoke RaiseError with ContentWarning as its operand. The decision on whether or not to invoke RaiseError is based on the Current AbortPolicy of the Virtual Machine; see .

    Print

    The Print operator takes one operand

  • <message: OctetStringReference> and returns no results. It causes message to be issued to the print requestor in an implementation-dependent way.

    ExecuteTrapped

    The ExecuteTrapped operator takes one operand

  • <P: Procedure> and returns one result
  • <trapped: Boolean>

    ExecuteTrapped executes the Procedure P (as if by the Execute operator). If P runs to completion normally, ExecuteTrapped returns a value of false on the Operand Stack. If P terminates prematurely as a result of executing the RaiseException operator, ExecuteTrapped returns the value true on the Operand Stack. Regardless of the outcome, the interpreter resumes execution at the next object in normal sequence after ExecuteTrapped operator.

    StoreErrorInfo

    The StoreErrorInfo Procedure in ErrorDict takes one operand

  • <errorname: Name> and returns one result
  • <errorname: Name>

    This Procedure is executed by the interpreter when an interpreter error occurs; it records information about the error and the context in which it occurred into ErrorInfoDict (see ).

    The default StoreErrorInfo Procedure sets the value of the newerror key to true, then sets the values of the errorname, command, ostack, and cstack keys to the appropriate values (see ). A document may redefine the value of the StoreErrorInfo key, but to ensure correct interpretation of subsequent document errors, the new StoreErrorInfo Procedure must set the newerror key in ErrorInfoDict to true as part of its execution, and must ensure that errorname remains on the stack following execution of the new StoreErrorInfo Procedure.

    If the default StoreErrorInfo Procedure is explicitly executed by a document in content, an interpreter error occurs.

  • Due to the desirability of having StoreErrorInfo always accessible from the current context of interpretation, an exact copy of the StoreErrorInfo key/value pair of ErrorDict is maintained by the interpreter in SystemDict.
  • If the value of StoreErrorInfo is redefined, it is often necessary to redefine the value of the ReportErrorInfo Procedure as well (see ).

    ReportErrorInfo

    The ReportErrorInfo Procedure in ErrorDict takes no operands and returns no results. This Procedure is executed by the interpreter for exceptions unhandled by the document. It sets the value of the newerror key in ErrorInfoDict to false, then issues an error message to the print requestor in an implementation-dependent manner, based on the information in ErrorInfoDict (see ).

    A document may redefine the value of ReportErrorInfo, but to ensure correct interpretation of subsequent document errors, the new ReportErrorInfo Procedure must set the newerror key in ErrorInfoDict to false as part of its execution.

    If the default ReportErrorInfo is executed other than from within a content exception handler Procedure, the results are implementation-dependent and may be meaningless, but no interpreter error occurs. Due to the desirability of having ReportErrorInfo always accessible from the current context of interpretation, an exact copy of the ReportErrorInfo key/value pair of ErrorDict is maintained by the interpreter in SystemDict.

    Interpreter Errors

    With the exeception of Timeout, Most interpreter errors occur only during the interpretation of an value of type Operator in content. However,Timeout shall occur only between the execution of objects and StackOverflow may occurl when interpreting a value other than an Operator as well as when interpreting an Operator. Interpreter errors may result from a variety of causes including, for example, divide by zero and syntax error.

    When an interpreter error occurs, the Content Processor attempts to restore the state of the Operand Stack to the state which existed immediately prior to interpretation of the Operator which caused the error. The results of this attempt are implementation dependent. Next, it pushes that Operator value on the Operand Stack. Finally, it places the name of the interpreter error (see ) on the Operand Stack and executes the RaiseError operator. The RaiseError operator is executed directly by the interpreter, without searching for a value bound to the name RaiseError in the Context Stack.

    The subsequent activity of the Content Processor is under control of the error Procedure invoked by the RaiseError operator.

    Error Procedures and Dictionaries

    All of the default error Procedures place the name of the corresponding interpreter error on the Operand Stack, then invoke the StoreErrorInfo Procedure from ErrorDict, then execute the RaiseException operator.

    The default contents of ErrorDict include the StoreErrorInfo Procedure, the ReportErrorInfo Procedure, and the set of all error-specific Procedures (see for a list of all errors). A reference to ErrorDict itself is bound to the key ErrorDict in SystemDict.

    The default contents of ErrorInfoDict, and their semantics, are described in . A reference to ErrorInfoDict itself is bound to that key ErrorInfoDict in SystemDict.

    Possible Interpreter Errors

    The following is the default list of possible interpreter errors and their semantics. The list of possible interpreter errors on a given implementation may be a superset of this list. The name of the exception raised as a result of the occurence of each error is the same as the name of the underlying error. In the case that by the semantics of this International Standard more than one exception could be raised for a given operator execution, the exception that is actually raised is defined by the implementation.

    Throughout this International Standard, the descriptions of operator semantics include specific conditions which cause exceptions during the execution of the operator. There are, in addition, certain generic errors which can cause an exception during the execution of almost any operator. These generic errors are InvalidAccess, LimitCheck, NoMemory, RangeCheck, StackOverflow, StackUnderflow, and TypeCheck.

    The following is a list of the possible interpreter errors defined by this International Standard: Errormeaning ContentWarningRaiseWarning operator executed on a Virtual Machine in which the Current Abort Policy has a value of dpi::abort-policy::on-warning ContextStackOverflowAttempt to PushContextStack with a full Context Stack ContextStackUnderflowAttempt to PopContextStack with no removable Dictionaries on the Context Stack DataErrorUnexpected and illegal characters occur in the StreamObject that is input to a filter InvalidAccessAttempt to violate an object's access attribute. This error shall occur upon attempting to execute an object with a NoAcesss attribute, upon attempting to read an object with an ExecuteOnly or NoAcesss attribute, or upon attempting to modify an object with a ReadOnly, ExecuteOnly or NoAcesss attribute. Putting an object reference onto the Operand Stack is not an access to the referenced object. InvalidExitExit operator executed outside any looping operator. InvalidFontInvalid operand to FindFont InvalidRestoreAttempt to RestoreState when Context Stack or Operand Stack contains ObjectReferences to objects created after the SaveObject operand to RestoreState was created IOErrorAn implementation-dependent error has occurred while reading from a StreamObject LimitCheckAn implementation limit (one for which there is no specific exception Procedure defined) has been exceeded NoCurrentPositionAttempt to execute a path construction operator other than SetPosition, ArcToClockwise, or ArcToCounterClockwise when the current path is the null path NoMemoryThere is not enough memory available to execute the operator successfully RangeCheckThe value of some operand or the value bound to some key in a dictionary that is an operand of the operator currently being executed is of the correct type, but is not in the allowable range for that operand of that operator. If the operand is a reference to a Vector or Octetstring object into which values are to be placed and the composite object is not of sufficient size to hold all such values, then RangeCheck shall occur StackOverflowThe implementation limit on the depth of the Operand Stack has been exceeded StackUnderflowNot enough operands on the stack for the operator being executed SyntaxErrorDocument content encountered which is not in accordance with the Content Interchange Format (see clause 37 and clause 38) TimeoutThe default implementation time limit for processing a document, or the time limit specified via DPI in the document, has been exceeded TypeCheckAn operand of the operator currently being executed is of the wrong value type UndefinedKeyA key given as an operand to the operator currently being executed is not in the Dictionary operand of that operator, in any Dictionary on the Context Stack, or in the enumerated list of Names required by that operator as appropriate to that operator UndefinedResourceThere is no resource of the specified type bound to the INTERNAL RESOURCE IDENTIFIER operand provided to FindResource UndefinedResultOver/underflow or meaningless result, such as an attempt to Divide by 0 or take the SquareRoot of a negative number UnmatchedMarkThere is no Mark value on the Operand Stack.

    ErrorInfoDict

    The following subclauses describe the key/value pairs in the default ErrorInfoDict, and their semantics. Mandatory key/value pairs shall be present in all implementations; optional key/value pairs may be absent in some implementations, in which case default values for the missing key/value pairs are assumed by the exception handling function.

    newerror

    The mandatory key/value pair <newerror: Boolean> is used by the interpreter to track error handling. By default, the value of the key is set to true by the StoreErrorInfo Procedure, and is set to false by the ReportErrorInfo Procedure. Documents which alter the values of these Procedures must retain the original semantics involving newerror (see and ).

    errorname

    The mandatory key/value pair <errorname: Name> is the name of the error that was invoked. A complete list of error names is given in .

    command

    The mandatory key/value pair <command: Any> has as its value the Operator being executed by the interpreter at the time the error occurred. If no Operator was being interpreted at the time the error occured, either its value is the the object being interpreted or, in the case of TimeOut, its value may be undefined.

    ostack

    The mandatory key/value pair <ostack: VectorReference> is a reference to a Vector containing a snapshot of the entire Operand Stack immediately before the error occurred, stored as if by the MakeandStoreVector operator.

    dstack

    The mandatory key/value pair <dstack: VectorReference> is a reference to a Vector containing a snapshot of the entire Context Stack immediately before the error occurred, stored as if by the ContextStack operator.

    recordstacks

    The optional key/value pair <recordstacks: Boolean> controls whether the default StoreErrorInfo Procedure (see ) is to record the ostack and dstack snapshots. A value of true means the contents of the stacks are recorded. A value of false means the contents of these stacks are not recorded. If this key/value pair is not present in ErrorInfoDict, the default StoreErrorInfo Procedure operates as if it were present and had the value true.

    Print requestor

    The print requestor is an implementation defined channel which is sent information about the presentation of DOCUMENTs, including messages associated with errors and warnings. Whether and how this information is presented is implementation dependent. this information may be presented on a series of pages that follow the document and/or sent back to the process that invoked the SPDL process by a reverse channel whose structure and protocols are not defined by this International Standard.