How do I discover what exceptions are thrown?

250 views
Skip to first unread message

Bruce Eckel

unread,
Sep 14, 2012, 12:46:08 PM9/14/12
to scala...@googlegroups.com
Here's my example: I'm looking at the ScalaDoc for io.Source.fromFile, but I don't see exceptions specified anywhere. Is there a place to look for them?

Thanks...

Josh Suereth

unread,
Sep 14, 2012, 1:08:28 PM9/14/12
to Bruce Eckel, scala...@googlegroups.com

Scala doesn't use checked exceptions, so if they are not documented, it could be anything.   That's kinda true anyway....

Bruce Eckel

unread,
Sep 14, 2012, 1:27:23 PM9/14/12
to scala...@googlegroups.com, Bruce Eckel
But ... the client programmer still needs to know what to catch, regardless of whether there are checked exceptions.

For example, Python does not have checked exceptions, but the docs still tell you what exceptions are thrown.

Exceptions are part of the interface, checked or no. To program against the interface, you have to know it.

Are you saying this is a design choice, not to document exceptions?

Josh Suereth

unread,
Sep 14, 2012, 1:30:27 PM9/14/12
to Bruce Eckel, scala...@googlegroups.com

No, I'm saying if you don't see documented exceptions then it's a flaw of the documentation.  

I've been meaning to sweep through the std. Lib and help document things more.   If you open tickets, it'll give me areas to focus on.

Alex Cruise

unread,
Sep 14, 2012, 1:43:58 PM9/14/12
to Bruce Eckel, scala...@googlegroups.com
On Fri, Sep 14, 2012 at 10:27 AM, Bruce Eckel <bruce...@gmail.com> wrote:
But ... the client programmer still needs to know what to catch, regardless of whether there are checked exceptions.

It's not used often, because it's mainly poo-poohed as being merely for Java compatibility, but we do have the @throws annotation, which is translated into the appropriate Java signature.

trait Foo {
  @throws(classOf[OhNoHeDidntException])
  def bar = ...
}

But the annotation has absolutely no effect on the front-end of the compiler, just in the way bytecode is generated. That is, it cannot cause warnings or errors.
 
Are you saying this is a design choice, not to document exceptions?

I'd say it's an oversight/omission that's extremely widespread in Scalaland. :)  

Some will say that politically correct Scala code shouldn't use exceptions, but in practice, from an exception handling standpoint, a lot of code bases are just like Java, except without checked exceptions. :)

There *is* a nonzero community of people who would like it if we could re-introduce checked exceptions in selected places.  Such people are usually told to wait for an effect system. :)

-0xe1a

Bruce Eckel

unread,
Sep 14, 2012, 1:48:52 PM9/14/12
to Alex Cruise, scala...@googlegroups.com
Since I seem to have been significantly responsible for starting the Java checked exceptions debate in the first place, I definitely don't vote for checked exceptions in Scala.

But if (A) Scala needs to interact seamlessly with Java and (B) Scala libraries throw exceptions, they need to be documented.

-- Bruce Eckel

Bruce Eckel

unread,
Sep 14, 2012, 1:49:13 PM9/14/12
to Alex Cruise, scala...@googlegroups.com
Since I seem to have been significantly responsible for starting the Java checked exceptions debate in the first place, I definitely don't vote for checked exceptions in Scala.

But if (A) Scala needs to interact seamlessly with Java and (B) Scala libraries throw exceptions, the

On Fri, Sep 14, 2012 at 11:43 AM, Alex Cruise <al...@cluonflux.com> wrote:

Bruce Eckel

unread,
Sep 14, 2012, 1:48:54 PM9/14/12
to Josh Suereth, scala...@googlegroups.com
This seems to me to be something that needs a tool to either automatically generate the exception specifications or at the least to tell when they are missing. Doing it by hand is going to be endless whack-a-mole.

Is such a tool a reasonable thing to put into a ticket?

I also have been wondering how to bring up something I think is important, even if it means a ton of work. I believe that it would be a huge help if there could be a basic example for every method in the docs. Right now the docs are about as obscure as they can get, especially for beginners. Examples are the best way to show things. A lot to ask, I know, but the current state of the docs is holding back adoption.

To see an example of an exceptionally well-documented language, see http://golang.org/. Those folks continue to amaze me, and I think set the standard for an easy learning curve.

Josh Suereth

unread,
Sep 14, 2012, 1:59:52 PM9/14/12
to Bruce Eckel, scala...@googlegroups.com

There's a big issue with such a tool.   Do you always want us to document that out of memory, interruption, linkage errors can happen to any method, anywhere?

No, it's a subset you care about.   Like for scala.io.Source you want to know what to do with IOExceptions, as you already know a whole host of JVM exceptions could be thrown.

How is a tool supposed to understand *that*.   Now the tool could look for direct throw clauses, but that doesn't help when using java libraries.

"Ah", you say, "It can pull direct throws and checked java exceptions".   What about IllegalArgumentException, or other unchecked validation messages?

Basically, they need a human to document what they are, why they are thrown and how to recover.   Otherwise you still have to treat them as a black box "O NOES".

That doesn't mean a tool wouldn't be useful.  I think it's worth an effort.   However the results still need to be curated by a human.

Note:  we haven't done a doc spree in a while, but perhaps we should do one where we just document exceptions would be excellent.

- Josh

Bruce Eckel

unread,
Sep 14, 2012, 2:18:19 PM9/14/12
to Josh Suereth, scala...@googlegroups.com
My own experience with things like this is that, without a tool, it's simply impossible to get right. Especially with such a large body of code, and evolving at that.

Simon Ochsenreither

unread,
Sep 14, 2012, 2:36:19 PM9/14/12
to scala...@googlegroups.com, Bruce Eckel
I would be on board documenting @throws. There is just one issue: There is both a @throws annotation _and_ a @throws ScalaDoc tag, which more or less duplicate each other:

/** This method does ...
  * @throws IllegalArgumentException if `a` is less than 0. */
@throws(classOf[IllegalArgumentException])
def foo(a: Int) = ...

It's not a show-stopper at all, just annoying that we have to repeat ourselves here.

So we would probably need to decide if we're happy with the current solution, or if we want to do a different approach (like

@throws(classOf[IllegalArgumentException], "if `a` is less than 0.")

, which isn't perfect too, because then we would have an argument to @throws which we would currently only use in documentation, not for compilation or runtime.

Having worked in the ScalaDoc source I can tell you that it is pretty confusing to have both... :-)

@Bruce: Thanks for bringing up and raising awareness for these issues!

Simon Ochsenreither

unread,
Sep 14, 2012, 2:47:31 PM9/14/12
to scala...@googlegroups.com, Bruce Eckel
Ouch ... looks like I was the one implementing ScalaDoc's @throws in the first place ... https://issues.scala-lang.org/browse/SI-4421 :-/

@Bruce: Are there any places which would need prioritized fixing?

@Josh: Would it make sense to establish some "best practices" regarding @throws?

For instance, I'm wondering what's the right place to add these annotations in the collection hierarchy? Would we need to add them to each and every method, or is there a way of inherting it? Or just use @macro? Maybe we need to have a look at what Java does here ...

Additionally, I'm thinking about mentioning it in the Scala style guide.

On top of that I'm wondering if a large scale migration of https://wiki.scala-lang.org/display/SW/Writing+Documentation to http://docs.scala-lang.org/style/scaladoc.html would make sense or if we should split the Scala style guide into "code" and "documentation" parts as it gets longer.

Bruce Eckel

unread,
Sep 15, 2012, 3:00:35 PM9/15/12
to Simon Ochsenreither, scala...@googlegroups.com
I'm not familiar enough yet with the whole doc set to make suggestions.

I'm a really big fan of automation tools, though, so anything that automates is going to help. Maybe something could be done with macros?

Simon Ochsenreither

unread,
Sep 15, 2012, 3:39:59 PM9/15/12
to scala...@googlegroups.com, Simon Ochsenreither
I'm a really big fan of automation tools, though, so anything that automates is going to help. Maybe something could be done with macros?

Probably not macros ... but shouldn't the compiler be able to at least create the list of possible thrown exceptions for us (minus the "usual" ones)? (Josh?)
 

Philip Köster

unread,
Sep 16, 2012, 3:00:35 AM9/16/12
to Bruce Eckel, Alex Cruise, scala...@googlegroups.com
Am 14.09.2012 19:48, schrieb Bruce Eckel:
> Since I seem to have been significantly responsible for starting the
> Java checked exceptions debate in the first place, I definitely don't
> vote for checked exceptions in Scala.

Bruce, I do see the advantages of having checked exceptions. The idea
wasn't bad. But in practise, it never quite worked out. Looking at the
Java type system, why would I not have to catch RTEs subclassing
Exception, and why would I not have to catch Errors subclassing
Throwables? That was never natural. It's especially when people started
to throw new IllegalStateException(ex) where things got funky. So the
experiences made with checked exceptions weren't overly positive in the
first place.

Alex Cruise

unread,
Sep 17, 2012, 1:16:47 PM9/17/12
to Simon Ochsenreither, scala...@googlegroups.com
On Sat, Sep 15, 2012 at 12:39 PM, Simon Ochsenreither <simon.och...@gmail.com> wrote:
I'm a really big fan of automation tools, though, so anything that automates is going to help. Maybe something could be done with macros?

Probably not macros ... but shouldn't the compiler be able to at least create the list of possible thrown exceptions for us (minus the "usual" ones)? (Josh?)

Effect system. Effect system. Effect system.  Everybody now! :)

-0xe1a

Rex Kerr

unread,
Sep 17, 2012, 1:24:27 PM9/17/12
to Alex Cruise, Simon Ochsenreither, scala...@googlegroups.com
Yes please, effect system!  (One general enough to handle units of measurement also, thank you!)

  --Rex

P.S. One general enough to be able to detect linearization of mutable effects also, please?  Branches are way harder to reason about than linear paths.

P.P.S. And a pony.

Simon Ochsenreither

unread,
Sep 17, 2012, 5:44:56 PM9/17/12
to scala...@googlegroups.com, Alex Cruise, Simon Ochsenreither
Yes please, effect system!  (One general enough to handle units of measurement also, thank you!)
How are they related? And isn't the UoM stuff mostly solved?

Rex Kerr

unread,
Sep 17, 2012, 6:31:13 PM9/17/12
to Simon Ochsenreither, scala...@googlegroups.com, Alex Cruise
The effects system would benefit from a robust tagging system.  You could special-case it so that it only keeps track of whether something was mutated, or you could have a general tagging system that among other things tags things as "immutable" and methods as "immutable-preserving".

You then could then extend it to tell you whether the property of local-mutability was preserved.  This is really valuable since if you

  (x /: ys){ (xi, y) => y.messWithTheInternalsOf(x) }

you have absolutely no problem that you didn't recreate xi at every step in the fold, as long as y has no way to store x or its internals in that call and start futzing with it later.  You might also want to check the property of linear-mutability, where you could (provably) replace your mutable variable with a chain of immutable ones without reorganization of the tree.  For example,

  val x = xs.next

is not really a problem.  Pretty obvious what is going on.

  val x = if (p(xs.next)) f(xs.next) else g(xs.next, xs.next)

is dramatically more dangerous (and not just because you aren't checking whether the iterator has run dry).  Plus, if you can do this, you could potentially count points of mutation, which can serve as another check that you know what you're doing.

Anyway, if you have these sorts of capabilities to tag variables with information relevant to the compiler, then tagging them with units should be easy enough.  Existing solutions don't run with full runtime performance without compiler plugins and handle unit math.  A completely generic tagging system could (without needing the hooks into the compilers' analysis that effects need).  You could try to force marker traits or monads into service, but they really don't solve the tagging problem elegantly.

  --Rex

Stefan Wagner

unread,
Sep 18, 2012, 9:08:37 PM9/18/12
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 15.09.2012 21:39, Simon Ochsenreither wrote:
>
> Probably not macros ... but shouldn't the compiler be able to at
> least create the list of possible thrown exceptions for us (minus
> the "usual" ones)? (Josh?)

If a class of mine expects an XStream which is a trait which returns a
number of bytes, for example. In some cases it might be from a binary
file being read, in other cases from a funky device, sometimes from a
server process. But since it is a Trait, it might only be clear at
runtime, which exceptions could be thrown.

- From everywhere where a class is flexible enough to call dynamic
methods, configured and combined at runtime, it's unclear which
exceptions can be thrown.

If code is altered, and a private method a is replaced by a private
method b, both with different exceptions thrown, every code which
relies on those methods will --- ?

That doesn't mean that I don't want known, possible exceptions to be
documented.

Maybe I'm missing something.

- --

Tschööö--->...Stefan
- ---------------------------
Don't visit my homepage at:
http://home.arcor-online.net/hirnstrom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlBZGxUACgkQQeATqGpDnRr0fQCfX1h3WziIrNJJ9/xkVLxz8S3i
+lkAnRnOOs/8pXnyEPN5hDZit7rQjFLU
=dw3H
-----END PGP SIGNATURE-----

Simon Ochsenreither

unread,
Sep 18, 2012, 10:27:53 PM9/18/12
to scala...@googlegroups.com
Yes, right. It wouldn't be completely trivial.

I'm already working on simplifying the amount of code/work you have to do for throws and hope I can get it into 2.10.

Instead of having to duplicate/separate the throws-information between ScalaDoc and code...


/** This method does ...
  * @throws IllegalArgumentException if `a` is less than 0. */
@throws(classOf[IllegalArgumentException])
def foo(a: Int) = ...

... I'm working on providing the following option instead:

/** This method does ... */
@throws[IllegalArgumentException]("if `a` is less than 0")
def foo(a: Int) = ...

It is currently stuck because of code duplication between GenASM and GenJVM, and some code/style questions, but I hope I can figure it out today.

Bye,

Simon

Stefan Wagner

unread,
Sep 18, 2012, 11:24:22 PM9/18/12
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 14.09.2012 19:48, Bruce Eckel wrote:

> ... I also have been wondering how to bring up something I think is
> important, even if it means a ton of work. I believe that it would
> be a huge help if there could be a basic example for every method
> in the docs. Right now the docs are about as obscure as they can
> get, especially for beginners.

I advocate this suggestion.

> Examples are the best way to show things. A lot to ask, I know, but
> the current state of the docs is holding back adoption.

Yes. Very often examples help to understand. Especially for users, not
fluent in english language.

Maybe an annotation would help in identifying code without examples,
code which is example-complete. It could be an (Anreiz) to see
automated progress bars ...

> To see an example of an exceptionally well-documented language,
> see http://golang.org/. Those folks continue to amaze me, and I
> think set the standard for an easy learning curve.
>


- --

Tschööö--->...Stefan
- ---------------------------
Don't visit my homepage at:
http://home.arcor-online.net/hirnstrom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iEYEARECAAYFAlBZOuYACgkQQeATqGpDnRrgDACfXHxKTcvbZmcL7nuSG/qZEQeL
ClcAn27/p6j+VHytSYcUcCMlP8+idmRX
=R4Q0
-----END PGP SIGNATURE-----

Naftoli Gugenheim

unread,
Sep 23, 2012, 10:24:51 PM9/23/12
to Stefan Wagner, scala...@googlegroups.com
I think it's also been mentioned, it would be interesting if the code examples in scaladoc comments were actually runnable tests.

Roland Kuhn

unread,
Sep 24, 2012, 1:03:24 AM9/24/12
to Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
Hi Naftoli,

24 sep 2012 kl. 04:24 skrev Naftoli Gugenheim:

I think it's also been mentioned, it would be interesting if the code examples in scaladoc comments were actually runnable tests.

+[a lot], profoundly seconded! This is the only way to keep the comments’ sample code in sync with refactorings.

What is needed to make this happen?

Regards,

Roland

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn


Daniel Sobral

unread,
Sep 24, 2012, 9:28:56 AM9/24/12
to Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
On Mon, Sep 24, 2012 at 2:03 AM, Roland Kuhn <goo...@rkuhn.info> wrote:
> Hi Naftoli,
>
> 24 sep 2012 kl. 04:24 skrev Naftoli Gugenheim:
>
> I think it's also been mentioned, it would be interesting if the code
> examples in scaladoc comments were actually runnable tests.

It has been mentioned many times.

>
> +[a lot], profoundly seconded! This is the only way to keep the comments’
> sample code in sync with refactorings.
>
> What is needed to make this happen?

Infrastructure. Most of the code there depends on context. I think the
easiest way of accomplishing such tests is to execute them like this:

For class X on package a.b.c:

import a.b.c.X
object Test {
// all code on class description
// all code on each method
}

For object X on package a.b.c:

import a.b.c.X
import X._
object Test {
// all code on object description
// all code on each method
}

Now, for the problems. The above alone will require code to be
rewritten, but, then, that's the very point. On the other hand, I have
no idea how to handle code on inherited docs, nor code associated with
nested members (for example, (new RegexParsers).Parser).

I'd put the code to do all of this (I mean, generate the above test
code, not run it) on Scaladoc, since it knows better what is code and
what is not, and can take decisions such as skipping or treating
differently code in example tags and such. It would also make it
available for Scala libraries. Scaladoc people might take objection to
that, though.
--
Daniel C. Sobral

I travel to the future all the time.

Matthew Pocock

unread,
Sep 24, 2012, 9:40:55 AM9/24/12
to Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
I think we need something like the following:

/** This is scaladoc for my amazying class.
 *  Here's useful stuff about it.
 *
 * @ExampleBlock(setup)
import my.stuff._

val fourHorsemen = List("Conquest", "War", "Famine", "Death")
 */
object AmazeYourFriends {
  /** This performs the unheard of feat of finding strings containing the letter 'e'.
   *
   * @Example
@UseBlock(setup)

AmazeYourFriends.stringsContainingE(fourHoursemen)
@ExpectedOutput(List("Conquest", "Famine", "Death")
   */
  def stringsContainingE(items: List[String]): List[String] = items filter (_.contains('e'))
}

Examples will typically rely upon a small amount of boilerplate for importing the right things and constructing standard datastructures. These need to be captured once and re-used. I'm not particularly tied to any of the names I've used here. Some sort of example quote e.g. ```example.code``` would be just as fine.

Matthew
--
Dr Matthew Pocock
Integrative Bioinformatics Group, School of Computing Science, Newcastle University
skype: matthew.pocock
tel: (0191) 2566550

Haoyi Li

unread,
Sep 24, 2012, 10:30:10 AM9/24/12
to Matthew Pocock, Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
As an alternative for python style "run any code in the comments"-style doctests, would it be more feasible to instead pull code from the unit tests to use in the docs? Something like

/**
 * This is a function which does stuff
 * It calculates a value and returns it
 * 
 * @param input is the input to the function
 * @return the input + 2
 * @scalatestExample(ExampleSuite.class, "basic test")
 */
def func(input: Int) = input + 2

...

class ExampleSuite extends FunSuite {
  test("basic test") {
    assert(func(4) === 6)
  }
  test("advanced test") {
    assert(func(5) === 7)
    assert(func(6) === 8)
    assert(func(7) === 9)
    ...
  }
}

The doc generator could then pull the relevant source code from the unit tests and place it inline in the docs, nicely formatted and all. This would avoid having to create a whole new set of infrastructure for creating/executing tests-in-comments, re-using common setup/teardown code, etc.: all this is already provided by scalatest or specs2.

This would require putting the example code in the tests and referencing it from the comments, but then we get the whole testing/running/etc. infrastructure for free. 

The explicit link from the function/class to the example in the tests could be used by Scaladoc or the IDE to let the user quickly jump to the source code of the example, which is handy. Furthermore, this example test would probably be followed by other related tests which exercise more advanced functionality which would be very handy for someone trying to figure out how the function works.

-Haoyi

Tim Pigden

unread,
Sep 24, 2012, 10:39:35 AM9/24/12
to Haoyi Li, Matthew Pocock, Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
Extracting it from tests rather than the source has the advantage that if you did a doc day more people could participate without anyone worrying about breaking the libraries.

Matthew Pocock

unread,
Sep 24, 2012, 11:34:00 AM9/24/12
to Haoyi Li, Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
Hi,

I've some sympathy for re-using code from a test harness - on the surface, examples and tests seem to share a lot of required tooling and seem to be doing something similar. However, what I was hoping was that we'd get code attached to the class/method/field documentation that we could cut/paste into a REPL session and expect to work, perhaps with some js wizardry to collapse away imports and other boilerplate, and that this code is an 'illustrative example' of how you could use the code yourself to do something useful.

Unit tests don't really work in this style. It's not clear what code you'd need to pull into the boilerplate, and the way you test a method is usually not how you would explain to someone how they could find it useful. I'd be totally behind an effort to link from scaladoc to the test code that exercises that code (or is the spec for it), but I don't think that this constitutes 'an illustrative example of using the code'. Similarly, I'd be completely stoked to be able to drop-down the implementation of a def in the scaladoc (yes I know there are links to an external page with the source now), but this doesn't tell us how you could use this def in your own program to solve your own problems.

There are also issues of compilation phases and tooling. You'd want the examples to be available to scaladoc, which means scaladoc will need to process both your production source and your example source. If the examples are coming from some parallel src/examples/scala directory, this is a bit of change from the current scheme. If the examples where inline with the production source, then scaladoc would spit out the docs to e.g. target/scaladoc and the synthetic code for the tests to e.g. target/scaladoc-examples, which a later phase could then do the normal test-harness thing with to validate that they are compilable and runnable and give the expected output.

Perhaps someone who actually knows the compiler and the sbt/maven plugins is better placed to comment on this though. Tools /can/ do anything, but I'm not the poor victim who would have to maintain them.

Matthew

Daniel Sobral

unread,
Sep 24, 2012, 7:30:40 PM9/24/12
to Matthew Pocock, Haoyi Li, Roland Kuhn, Naftoli Gugenheim, Stefan Wagner, scala...@googlegroups.com
On Mon, Sep 24, 2012 at 12:34 PM, Matthew Pocock
<turingate...@gmail.com> wrote:
> Hi,
>
> I've some sympathy for re-using code from a test harness - on the surface,
> examples and tests seem to share a lot of required tooling and seem to be
> doing something similar. However, what I was hoping was that we'd get code
> attached to the class/method/field documentation that we could cut/paste
> into a REPL session and expect to work, perhaps with some js wizardry to
> collapse away imports and other boilerplate, and that this code is an
> 'illustrative example' of how you could use the code yourself to do
> something useful.

+1. I think that's a prerequisite: it must be pastable on REPL.

That's why I structured my suggestion as I did. It's reasonable to
expect the class in question to be in scope, and not far fetched to
expect object's contents to be imported. Examples throughout a class
description may depend on previous definitions, and it's not out of
the ordinary to have those definitions be in scope for example of
methods.

I personally think every other suggestion made to be awful. Keep it
light weight, or be prepared to write ALL the example code. I, for
one, won't bother with the heavy handed suggestions made.

And, in fact, that's probably something people should keep in mind. If
you haven't contributed docs with examples to Scaladoc, consider the
possibility that you are not well qualified to make suggestions on how
to make it work. Of course, anyone who has *read* Scaladoc can make
suggestions on what should happen from the user side -- such as having
all examples compilable.

joebowbeer

unread,
Sep 11, 2015, 8:50:56 PM9/11/15
to scala-user
Almost 3 years later to the date, and I follow in your footsteps: wondering what exceptions Source methods may throw...

I *know* that Source.fromFile and Source.getLines can/do throw various IO exceptions, but there's no mention of it. The Source doc says something about the report methods but that's a red herring AFAICT.
Reply all
Reply to author
Forward
0 new messages