com-lihaoyi / fansi

Scala/Scala.js library for manipulating Fancy Ansi colored strings
Other
227 stars 26 forks source link

IllegalArgumentException: Unknown ansi-escape [2m #46

Open kpodsiad opened 2 years ago

kpodsiad commented 2 years ago

Summary

One of the Metals users hit an issue when Metals wasn't displaying errors which came from ZIO test suite. After an investigation I found that issue is caused by Fansi. ZIO sets various ansi styles in their tests and at least one of them (Faint - "\u001b[2m") is unsupported by Fansi:

Caused by: java.lang.IllegalArgumentException: Unknown ansi-escape [2m at index 206 inside string cannot be parsed into an fansi.Str`

In Metals, we use Fansi to obtain plain text from bsp diagnostic before forwarding it to the lsp client.


Reproduction

//> using scala "2.13.8"
//> using lib "com.lihaoyi::fansi:0.3.0"

object Fansi extends App {
  val Reset = "\u001b[0m"
  val Faint = "\u001b[2m"

  val byHand = Faint + "Foo" + Reset

  println("Foo")
  println(byHand)

  val plainText: fansi.Str = fansi.Str(byHand).plainText

  println(plainText)
}

Behavior

➜  scala-cli run Fansi.scala
Compiling project (Scala 2.13.8, JVM)
Compiled project (Scala 2.13.8, JVM)
Foo
Foo
Exception in thread "main" java.lang.IllegalArgumentException: Unknown ansi-escape [2m at index 0 inside string cannot be parsed into an fansi.Str
        at fansi.ErrorMode$Throw$.handle(Fansi.scala:440)
        at fansi.ErrorMode$Throw$.handle(Fansi.scala:428)
        at fansi.Str$.apply(Fansi.scala:280)
        at Fansi$.delayedEndpoint$Fansi$1(Fansi.scala:13)
        at Fansi$delayedInit$body.apply(Fansi.scala:4)
        at scala.Function0.apply$mcV$sp(Function0.scala:39)
        at scala.Function0.apply$mcV$sp$(Function0.scala:39)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
        at scala.App.$anonfun$main$1(App.scala:76)
        at scala.App.$anonfun$main$1$adapted(App.scala:76)
        at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563)
        at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561)
        at scala.collection.AbstractIterable.foreach(Iterable.scala:926)
        at scala.App.main(App.scala:76)
        at scala.App.main$(App.scala:74)
        at Fansi$.main(Fansi.scala:4)
        at Fansi.main(Fansi.scala)

Expected Behavior

Fansi should parse \u001b[2m ansi code, as well as other styles defined in linked file from ZIO repository.

kpodsiad commented 2 years ago

Easy workaround for this issue - fansi.Str(<string with ansi styles>, ErrorMode.Strip).

jk-1 commented 1 year ago

I got same kind of exception message

java.lang.IllegalArgumentException: Unknown ansi-escape [0;93m at index 16 inside string cannot be parsed into an fansi.Str

when trying to run command ssh-ping -q -W 2 -c 1 -p 22 myhost with os.proc(...) which is part of os.lib.

I was using Ubuntu 20.04, Ammonite Repl 2.4.0 (Scala 2.12.13 Java 11.0.18)

See this how to reproduce the error

EDIT:

I also tested this with Scala standard REPL and Ammonite REPL

Using ammonite REPL command fails

amm
Loading...
Welcome to the Ammonite Repl 2.4.0 (Scala 2.12.13 Java 11.0.18)
jk-kptmp@ import scala.sys.process._  
import scala.sys.process._ 

jk-kptmp@ val res = "ssh-ping -q -W 2 -c 1 -p 22 myhost".!! 
java.lang.IllegalArgumentException: Unknown ansi-escape [0;93m at index 19 inside string cannot be parsed into an fansi.Str
  fansi.ErrorMode$Throw$.handle(Fansi.scala:419)
  fansi.ErrorMode$Throw$.handle(Fansi.scala:407)
  fansi.Str$.apply(Fansi.scala:272)
  fansi.Str$.implicitApply(Fansi.scala:227)
  pprint.Renderer.$anonfun$rec$33(Renderer.scala:149)
  pprint.Result$.fromString(Result.scala:53)
  pprint.Renderer.rec(Renderer.scala:149)
  pprint.PPrinter.tokenize(PPrinter.scala:104)
  ammonite.repl.FullReplAPI$Internal.print(FullReplAPI.scala:106)
  ammonite.repl.FullReplAPI$Internal.print$(FullReplAPI.scala:61)
  ammonite.repl.FullReplAPI$$anon$1.print(FullReplAPI.scala:34)

But when using scala REPL command executes without failures

scala
Welcome to Scala 2.12.8 (OpenJDK 64-Bit Server VM, Java 11.0.18).
Type in expressions for evaluation. Or try :help.

scala> import scala.sys.process._
import scala.sys.process._

scala>  val res = "ssh-ping -q -W 2 -c 1 -p 22 myhost".!!
res: String =
"SSHPING myhost

--- myhost ping statistics ---
1 requests transmitted, 0 requests received, 100% request loss
"

scala> 

Running the command in Ubuntu MATE terminal the output is

ssh-ping -q -W 2 -c 1 -p 22 myhost
SSHPING myhost

--- myhost ping statistics ---
1 requests transmitted, 0 requests received, 100% request loss