12
$\begingroup$

According to: tutorial/WolframSystemSessions

Initialization

On startup, the Wolfram Language kernel does the following:

  • Performs license management operations.

  • Runs Wolfram Language commands specified in any -run options passed to the kernel executable.

  • Runs the Wolfram Language commands in the systemwide initialization file $BaseDirectory/Kernel/init.m.

  • Runs the Wolfram Language commands in the user-specific initialization file $UserBaseDirectory/Kernel/init.m.

  • Loads init.m and Kernel/init.m files in Autoload directories.

  • Begins running the main loop.

So I'd say that packages in Autoload have a freedom to do everything since everything should be already loaded. Yet this example fails:

dir = FileNameJoin[{$UserBaseDirectory, "Autoload", "Fetch", "Kernel"}];

CreateDirectory[dir, CreateIntermediateDirectories -> True]

SetDirectory @ dir;

Export[
 "init.m",
 "Print @ StringTake[URLFetch[\"www.wolfram.com\"], 300]; ", 
 "Text"]

Now quit the Kernel and evaluate something. I only get messages:

URLFetch::invhttp: Couldn't resolve proxy name.

StringTake[$Failed, 300]

Throw::nocatch: Uncaught Throw[False] returned to top level.

Throw::nocatch: Uncaught Throw[False] returned to top level.

Throw::nocatch: Uncaught Throw[False] returned to top level.

General::stop: Further output of Throw::nocatch will be suppressed during this calculation.

Break::nofwd: No enclosing For, While, or Do found for Break[].

While normally this procedure works StringTake[URLFetch["www.wolfram.com"], 300].

Question What's the problem? What more do we need to know about the Initialization stack? Are there any workarounds?

Currently I'm just setting procedure via ScheduledTask to fire 2 seconds later. But that's just silly.

This is not a question about URLFetch (yet good to know this specific problem) but about things I have to know to not be surprised next time.

$\endgroup$
8
  • 3
    $\begingroup$ The basic problem, which is not so easy to fix, is that the kernel initialization code has protection against aborts. Since Throw/Catch are implemented internally using this (C code level) abort machinery, they are not functional during initialization, so running any code using them is problematic. See also this. $\endgroup$
    – ilian
    Commented Mar 17, 2016 at 15:03
  • $\begingroup$ If you're using Windows, you might want to take a look at Process Monitor. $\endgroup$
    – Silvia
    Commented Mar 17, 2016 at 17:05
  • $\begingroup$ @ilian so URLFetch::invhttp: Couldn't resolve proxy name. is caused somehow by the Catch/Throw issue you are talking about or is there something more? $\endgroup$
    – Kuba
    Commented Mar 31, 2016 at 11:41
  • $\begingroup$ Yes, that is the cause. $\endgroup$
    – ilian
    Commented Mar 31, 2016 at 13:40
  • 1
    $\begingroup$ See here, you'll find most things in sysinit.m $\endgroup$
    – Szabolcs
    Commented Nov 30, 2016 at 14:59

1 Answer 1

13
$\begingroup$

Update

Leaving my original answer below for historical purposes, however it only applies up until version 11.1.1.

As of version 11.2.0, the kernel startup initialization has been overhauled and this example (as well as others) now works correctly: placing the URLFetch call in init.m does result in an output like

<!doctype html>
<html lang="en" class="homepage">
<head>

<!-- begin framework head en -->

    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <meta name="msapplication-config" content="/b

This improvement was motivated in part by the new Persistence & Initialization framework, and I recommend Roman Maeder's presentation from the 2017 Wolfram Technology Conference.


To make my comment into an answer,

The basic problem, which is not so easy to fix, is that the kernel initialization code has protection against aborts. Since Throw/Catch are implemented internally using this (C code level) abort machinery, they are not functional during initialization, so running any code using them is problematic.

The URLFetch implementation does depend on Catch working correctly, as can be seen from

TracePrint[URLFetch["www.wolfram.com"], _Catch]

Some related questions are the following: (1), (2), (3), (4).

$\endgroup$
3
  • $\begingroup$ Can User and or Base Autoload be excluded from the initialization code but done as soon as the latter is finished? Is this problem expected to be solved in near future? $\endgroup$
    – Kuba
    Commented Apr 12, 2016 at 8:46
  • $\begingroup$ Does this mean that a package that uses Throw or Abort in its initialization cannot be auto-loaded? $\endgroup$
    – Szabolcs
    Commented May 12, 2016 at 12:48
  • $\begingroup$ @Szabolcs It seems not, but you can put RunScheduledTask[Get @ "Package`Package`", {5}] in init.m or whatever procedure you have in addition to Get. Then it will be fine. $\endgroup$
    – Kuba
    Commented May 12, 2016 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.