Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Clojure by

Suppose you have a lib that causes some errors during loading, like the following:

`
(ns broken-lib)

(} ; this line will cause a reader error
`

And then, if you {{require}} the lib, it would be added into {{loaded-libs}} in spite of the reader error, which makes {{require}} succeed silently after that.

user=> (contains? (loaded-libs) 'broken-lib) false user=> (require 'broken-lib) CompilerException java.lang.RuntimeException: Unmatched delimiter: }, compiling:(broken_lib.clj:3:3) user=> (contains? (loaded-libs) 'broken-lib) true user=> (require 'broken-lib) nil user=>

Things get worse if you have another namespace that requires a broken lib (say here {{broken-lib.core}}):

(ns broken-lib.core (:require [broken-lib :as lib]))

Although you'll get the actual error the first time you load the depending namespace, after that you'll find a wrong compiler exception thrown every time you try to reload it. The situation will last even after you actually do fix the code causing the original error.

`
user=> (require 'broken-lib.core)

CompilerException java.lang.RuntimeException: Unmatched delimiter: }, compiling:(broken_lib.clj:3:3)

user=> (require 'broken-lib.core :reload)
CompilerException java.lang.Exception: namespace 'broken-lib' not found, compiling:(broken_lib/core.clj:1:1)

user=> (require 'broken-lib.core :reload) ;; reload after fix the bug in broken-lib

CompilerException java.lang.Exception: namespace 'broken-lib' not found, compiling:(broken_lib/core.clj:1:1)
user=>
`

Cause:
The patch for CLJ-1116 made the {{ns}} macro blindly add the lib being defined into {{loaded-libs}} even if an error occurs during loading.

Approach:
Modify {{clojure.core/load-lib}} so that it removes the lib from {{loaded-libs}} on error.

7 Answers

0 votes
by

Comment made by: alexmiller

This patch seems somewhat removed from the cause - is there some way to instead prevent the lib from being added to loaded-libs in the first place?

0 votes
by

Comment made by: sohta

To do so, I think we need to revert CLJ-1116.

0 votes
by

Comment made by: alexmiller

I don't think this solution is good as is so moving to Incomplete.

0 votes
by

Comment made by: sohta

What kind of solution are you expecting for this problem?

To prevent the lib from being added to loaded-libs in the first place, I think ns macro needs to know where it is used from. It should immediately add the ns when used in the REPL for CLJ-1116, while it should defer adding the ns until completing loading whole the file without errors when used within a file.

0 votes
by

Comment made by: gshayban

Attached a similar approach as Shogo Ohta's original. Given the way ns now works, I see this approach as tenable.

To support dynamic ns creation at the REPL, CLJ-1116 wrote to loaded-libs inside the ns macro, and at the same time made some logic in load-lib and load-libs unnecessary. This set of patches undoes the side-effect when loading fails, and cleans up some dead conditionals.

New behavior: Given ns A which requires #{B, C}, if B loads but C doesn't, only B will be written to loaded-libs, and A and C will be undone. This improves the experience with load and fixes all of the annoying behavior in the ticket description.

NB: the 'require' patch entails:
If a lib is specified in an ns :require or :use, loading that lib the first time must result in an ns that corresponds exactly to the lib name. (There is not and has never been this restriction when calling load directly, but only via ns) I was surprised to find in the test suite an accidental lib with underscores where the loaded code results in a namespace with a dash. (Perhaps c.c.specs should specify a tighter spec for libs than 'simple-symbol?')

The commits are separated, with accompanying short explanatory comments.

0 votes
by

Comment made by: alexmiller

Note - CLJ-2026 may be made irrelevant by any fix to this broader problem and could then be pulled out.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1406 (reported by sohta)
...