Re: catching exceptions

On Apr 29, 2008, at 9:48 AM, Gabor Szabo wrote:

I must be missing something:

I am trying to get an iter on a line.

Sometimes the offset is too big so the below function throws
an exception:

$end_iter= $buffer->get_iter_at_line_offset($line, $end);

Gtk-ERROR **: Char offset 24 is off the end of the line at ....

The problem is that even if I put the expression in eval it does not
catch it.

When it says "$somename-ERROR" like that, it's not really an exception, but somebody calling g_error() down inside the C code. These are considered fatal error conditions.

Sure enough:

$ grep "is off the end of the line" gtk+/gtk/*.c
gtk+/gtk/gtktextiter.c: g_error ("Byte index %d is off the end of the line", gtk+/gtk/gtktextiter.c: g_error ("Char offset %d is off the end of the line",

Those are in the functions iter_set_from_byte_offset() and iter_set_from_char_offset().

The docs for gtk_text_buffer_get_iter_at_line_offset() say:

 * Obtains an iterator pointing to @char_offset within the given
 * line. The @char_offset must exist, offsets off the end of the line
 * are not allowed. Note <emphasis>characters</emphasis>, not bytes;
 * UTF-8 may encode one character as multiple bytes.

Can I catch this exception somehow?

With some work, yes, you can trap it with a perl handler. This is not really generic, though, and is not a proper solution to your problem.

use strict;
use Glib;

Glib::Log->set_handler ("Foo", [qw/fatal error critical warning/], sub {
        my ($domain, $flags, $message) = @_;
        use Carp;
        die Carp::longmess("$domain: $message");

eval {
        Glib->error ("Foo", "holy crap!");
if ($@) {
        print "We trapped a g_error() call, whose message was:\n"
            . "  \"$ \"\n";

As a workaround, can I get the length of a row from the Text::Buffer?

 * gtk_text_iter_get_chars_in_line:
 * @iter: an iterator
 * Returns the number of characters in the line containing @iter,
 * including the paragraph delimiters.
 * Return value: number of characters in the line

Looks like your best bet will be

   $iter = $buffer->get_iter_at_line ($line_index);
   $chars_in_line = $iter->get_chars_in_line ();
   if ($chars > $chars_in_line) {
       $chars = $chars_in_line;
   $iter->forward_chars ($chars);

So this new album took us quite a while, to get it together, to find a title and things like that - and we were travelling quite a bit - we made a few sort of gestures in the East, and a few gestures in the West, and then we got thrown out because of our gestures - this is something that we decided was an apt title for a thing that's called 'The Song Remains The Same'.
  -- Robert Plant, rambling to introduce a song

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]