Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Throwing a custom error

37 views
Skip to first unread message

Terry Burton

unread,
May 18, 2013, 10:44:25 PM5/18/13
to
Hi,

In Barcode Writer in Pure PostScript (BWIPP) it is possible for the user to provide invalid input data. At present we do not provide any useful form of input validation or error reporting and we simply allow the code to trip up and bomb out in meaningless ways on invalid data.

To provide a somewhat uniform approach to handling invalid user input I am investigating whether the PS code could raise a custom error and terminate for each circumstance (e.g. /bwipp.badCheckDigit or /bwipp.invalidCharacter, etc) that can be communicated to the user using whatever ordinary PS error handling is available in that environment.

So far I have a routine to customise the $error dict, invoke the handleerror procedure and quit:

/raiseerror {
$error exch /errorinfo exch put
$error exch /errorname exch put
$error /command //null put
$error /newerror true put
handleerror quit % Is quit the right thing to do here?
} bind def
...
badCheckDigitProvided {
/bwipp.badCheckDigit (Incorrect check digit provided) raiseerror
} if

This seems to work however it has the problem (at least with GhostScript) that the PS interpreter exits with a code of 0 indicating success:

$ gs raiseerror.ps
GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Error: /bwipp.badCheckDigit in null
Additional information: (Incorrect check digit supplied)
Current allocation mode is local
Last OS error: No such file or directory

$ echo $?
0

Whereas a pre-defined error (in the absence of a redefined handleerror) will normally cause GhostScript to terminate with a non-zero exit code:

$ cat bork.ps
%!PS
bork

$ gs bork.ps
GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Error: /undefined in bork
<...snip stack dumps...>
Current allocation mode is local
Current file position is 11
GPL Ghostscript 9.07: Unrecoverable error, exit code 1

$ echo $?
1

Is the throwing of custom errors a sensible thing to do? It should certainly provide higher-level applications ("frontends") that wrap BWIPP with a uniform mechanism for detecting and reporting errors - by parsing stdout/stderr or using a custom handleerror.

If so, is quit the appropriate operator to cease execution? And how might I ensure that the PS interpreter exits with a non-zero exit code?


Thanks,

Terry

luser- -droog

unread,
May 20, 2013, 1:04:37 AM5/20/13
to
On Saturday, May 18, 2013 9:44:25 PM UTC-5, Terry Burton wrote:
[...]
>
> Is the throwing of custom errors a sensible thing to do? It should certainly provide higher-level applications ("frontends") that wrap BWIPP with a uniform mechanism for detecting and reporting errors - by parsing stdout/stderr or using a custom handleerror.
>
>
> If so, is quit the appropriate operator to cease execution? And how might I ensure that the PS interpreter exits with a non-zero exit code?
>

Hopefully the ghostscript gurus will have something better,
but it might work to just use /undefined, but pack information into the undefined name itself. I know that sentence is terrible. How about an example?

...
dup type /integertype ne {
MUST_PASS_integer_TO_THIS_FUNCTION
} if

gs bails out with the expected:

Error: /undefined in MUST_PASS_integer_TO_THIS_FUNCTION

You can even embed spaces in the message:

(ERR: must pass integer to this function) cvn cvx exec

Error: /undefined in ERR: must pass integer to this function
Operand stack:

Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- %loop_continue --nostringval-- --nostringval-- false 1 %stopped_push .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval--
Dictionary stack:
--dict:1168/1684(ro)(G)-- --dict:0/20(G)-- --dict:77/200(L)--
Current allocation mode is local
Current file position is 55

ken

unread,
May 20, 2013, 2:52:19 AM5/20/13
to
In article <e4d4fc8b-af38-46db...@googlegroups.com>,
terry....@gmail.com says...


> If so, is quit the appropriate operator to cease execution? And how might I ensure that the PS interpreter exits with a non-zero exit code?

Essentially, you can't. By processing the error you prevent the
interpreter from 'seeing' it. So as far as the interpreter is
concerened, there is no error.

Technically this is correct, the input was fully processed in accordance
with the program instructions, so its correct that the interpreter exits
with a 'success' status.

However it might be possible, with some thought, to invoke the default
error handler after processing the error. Of course that will still
leave you with the PostScript error as well. Would you consider that to
be acceptable ?

The main uses of custom error handling are to prevent errors, so that
the page(s) is flushed up to the point of ther error, and printed.


Ken

Terry Burton

unread,
May 21, 2013, 10:01:08 AM5/21/13
to
On Monday, 20 May 2013 07:52:19 UTC+1, ken wrote:
> In article <e4d4fc8b-af38-46db...@googlegroups.com>,
> > If so, is quit the appropriate operator to cease execution? And how might I ensure that the PS interpreter exits with a non-zero exit code?
>
> Essentially, you can't. By processing the error you prevent the
> interpreter from 'seeing' it. So as far as the interpreter is
> concerened, there is no error.

Hi Ken,

Thanks for the information. After continuing my experiments I have concluded that I do not require a non-zero exit code, so I'm not requesting the GS be modified to act in a non-standard way.

For anybody who is interested my approach, BWIPP has been modified to include a raiseerror procedure (http://goo.gl/SjoSZ) that is invoked from the code to generate custom errors with names such as bwipp.someErrorName.

This allows frontends to BWIPP to prefix the code with an application-specific error handler that can do useful things with BWIPP errors but fall through to the existing error handler for other types of errors.

For example, the following presents BWIPP errors in a fixed format that can be trivially parsed by a calling CGI script to present a useful error message to the user:

errordict begin
/handleerror {
$error begin
errorname dup length string cvs 0 6 getinterval (bwipp.) eq {
(%stdout) (w) file
dup (\nBWIPP ERROR: ) writestring
dup errorname dup length string cvs writestring
dup ( ) writestring
dup errorinfo dup length string cvs writestring
dup (\n) writestring
dup flushfile end quit
} if
end //handleerror exec
} bind def
end
(bwipp.ps) run

The above is demonstrated in the BWIPP web based generator: http://goo.gl/vAiVg

Alternatively, one could easily imagine an error hander that renders the error in place of the expected barcode which might be most useful for applications such as the Scribus plugin, etc.

Thanks again for the help.


All the best,

Terry
0 new messages