Skip to content

Console.getCursorPosition throws a FormatException #11

Open
@kseo

Description

@kseo

The following program throws a FormatException when you press 'a' with another key simultaneously (e.g., press and 'a' and 's' at the same time).

import "package:console/console.dart";

void main() {
  Keyboard.init();

  Keyboard.bindKey("a").listen((_) {
    final pos = Console.getCursorPosition();
    print(pos);
  });
}
Unhandled exception:
FormatException: Invalid radix-10 number
[21
#0      int._throwFormatException (dart:core-patch/integers_patch.dart:111)
#1      int._parse (dart:core-patch/integers_patch.dart:101)
#2      int.parse (dart:core-patch/integers_patch.dart:58)
#3      Console.getCursorPosition.<anonymous closure> (package:console/src/base.dart:226:97)
#4      MappedListIterable.elementAt (dart:_internal/iterable.dart:413)
#5      ListIterator.moveNext (dart:_internal/iterable.dart:341)
#6      List.List.from (dart:core-patch/array_patch.dart:40)
#7      Console.getCursorPosition (package:console/src/base.dart:226:27)
#8      main.<anonymous closure> (file:///Users/kseo/dart/console.dart/example/keyboard.dart:7:25)

Console.getCursorPosition() synchronously writes ANSI 6h and reads the position. The underlying assumption is that there is no other interfering character while you perform Console.getCursorPosition().

But the exception above is caused because there is 's' character in the buffer when the callback is invoked for 'a' key. It is a race condition because the exception won't happen if you type 's' slightly slower than 'a'.

The cause is clear, but I am not sure how to fix this. If you just skip 's' in the buffer and perform Console.getCursorPosition(), the exception will disappear but 's' will be lost too. Once you read 's', there is no way to put it back at the front of the buffer.

I think the fundamental problem lies in that the API of console package mixes both synchronous and asynchronous API in a non-compatible way. It seems we can't reliably use synchronous APIs like Console.getCursorPosition() under the asynchronous key callback because "mixing synchronous and asynchronous reads is undefined".

Any suggestion?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions