Libs are blindly added into loaded-libs even if an error occurs during loading
Description
Environment
Attachments
- 18 Mar 2018, 08:05 PM
- 17 Apr 2014, 03:00 PM
Activity

Alex MillerJune 26, 2018 at 5:52 PM
Note - CLJ-2026 may be made irrelevant by any fix to this broader problem and could then be pulled out.

Ghadi ShaybanMarch 18, 2018 at 8:05 PM
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.
Shogo OhtaOctober 15, 2016 at 7:34 AM
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.

Alex MillerSeptember 22, 2016 at 7:41 PM
I don't think this solution is good as is so moving to Incomplete.
Shogo OhtaApril 17, 2014 at 3:21 PM
To do so, I think we need to revert CLJ-1116.
Details
Assignee
UnassignedUnassignedReporter
Shogo OhtaShogo OhtaApproval
VettedPatch
CodePriority
MajorAffects versions
Details
Details
Assignee
Reporter
Approval
Patch
Priority

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 intoloaded-libs
in spite of the reader error, which makesrequire
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 intoloaded-libs
even if an error occurs during loading.Approach:
Modify
clojure.core/load-lib
so that it removes the lib fromloaded-libs
on error.