Skip to content

ScalafmtSbtReporter suppresses real source of error #71

@rtoomey-coatue

Description

@rtoomey-coatue

sbt-scalafmt version: 2.2.1
TL;DR I believe I found a metaconfig issue, but in the meantime, it would be nice to have a plugin setting which disables ScalafmtSbtReporter so you don't have to publish local to figure out what is really going wrong. 🙏 Would happily contribute if you feel this is worthwhile.

What happened

I'm trying to debug an error where sbt scalafmtSbt is failing with a cryptic error on a specific metabuild source file:

java.util.NoSuchElementException: next on empty iterator /Users/rtoomey/workspace/foo/project/Bar.scala

First I reduced my .scalafmt.conf to nothing but

version = 2.2.1

Then I tried poking around Bar.scala to figure out what's upsetting scalafmt, and finally gave up.

When formatting source files, I was used to being about to set runner.debug = true and getting a detailed error. But this time, nothing except next on empty iterator.

Looking at the plugin

Finally, I went back into the source of the plugin itself and found
https://github.com/scalameta/sbt-scalafmt/blob/master/plugin/src/main/scala/org/scalafmt/sbt/ScalafmtPlugin.scala#L102

So I published the plugin locally with

val scalafmtInstance = globalInstance //.withReporter(reporter)

and immediately got that this line in metaconfig is an issue
https://github.com/olafurpg/metaconfig/blob/master/metaconfig-core/shared/src/main/scala/metaconfig/Position.scala#L25

error: /Users/rtoomey/workspace/foo/project/Bar.scala: java.util.NoSuchElementException: next on empty iterator
	at scala.collection.Iterator$$anon$19.next(Iterator.scala:954)
	at scala.collection.Iterator$$anon$19.next(Iterator.scala:952)
	at scala.collection.StringOps$$anon$1.next(StringOps.scala:682)
	at scala.collection.StringOps$$anon$1.next(StringOps.scala:680)
  | => rat metaconfig.Position.pretty(Position.scala:25)
	at metaconfig.ConfError$$anon$8.<init>(ConfError.scala:130)
	at metaconfig.ConfError$.parseError(ConfError.scala:130)
	at metaconfig.typesafeconfig.TypesafeConfig2Class$.gimmeSafeConf(TypesafeConfig2Class.scala:53)
	at metaconfig.typesafeconfig.TypesafeConfig2Class$.gimmeConfFromString(TypesafeConfig2Class.scala:11)
	at metaconfig.typesafeconfig.package$$anon$1.fromInput(package.scala:9)
	at org.scalafmt.config.Config$.fromInput(Config.scala:19)
	at org.scalafmt.config.Config$.fromHoconString(Config.scala:40)
	at org.scalafmt.util.StyleMap.$anonfun$x$1$1(StyleMap.scala:40)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
	at org.scalafmt.util.StyleMap.<init>(StyleMap.scala:37)
	at org.scalafmt.internal.FormatOps.<init>(FormatOps.scala:47)
	at org.scalafmt.Scalafmt$.format(Scalafmt.scala:59)
	at org.scalafmt.Scalafmt.format(Scalafmt.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.scalafmt.dynamic.ScalafmtReflect.format(ScalafmtReflect.scala:102)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$tryFormat$1(ScalafmtDynamic.scala:213)
	at scala.util.Try$.apply(Try.scala:213)
	at org.scalafmt.dynamic.ScalafmtDynamic.tryFormat(ScalafmtDynamic.scala:201)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$formatDetailed$1(ScalafmtDynamic.scala:107)
	at scala.util.Either.flatMap(Either.scala:341)
	at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:106)
	at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:68)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$2(ScalafmtPlugin.scala:114)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
	at scala.collection.Iterator.foreach(Iterator.scala:941)
	at scala.collection.Iterator.foreach$(Iterator.scala:941)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
	at scala.collection.IterableLike.foreach(IterableLike.scala:74)
	at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
	at scala.collection.TraversableLike.map(TraversableLike.scala:238)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
	at scala.collection.AbstractTraversable.map(Traversable.scala:108)
	at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:107)
	at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:153)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$3(ScalafmtPlugin.scala:319)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$3$adapted(ScalafmtPlugin.scala:308)
	at scala.Function1.$anonfun$compose$1(Function1.scala:49)
	at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
	at sbt.std.Transform$$anon$4.work(Transform.scala:67)
	at sbt.Execute.$anonfun$submit$2(Execute.scala:281)
	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19)
	at sbt.Execute.work(Execute.scala:290)
	at sbt.Execute.$anonfun$submit$1(Execute.scala:281)
	at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
	at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions