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$
  • 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 Mar 17 '16 at 15:03
  • $\begingroup$ If you're using Windows, you might want to take a look at Process Monitor. $\endgroup$ – Silvia Mar 17 '16 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 Mar 31 '16 at 11:41
  • $\begingroup$ Yes, that is the cause. $\endgroup$ – ilian Mar 31 '16 at 13:40
  • 1
    $\begingroup$ See here, you'll find most things in sysinit.m $\endgroup$ – Szabolcs Nov 30 '16 at 14:59
12
$\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$
  • $\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 Apr 12 '16 at 8:46
  • $\begingroup$ Does this mean that a package that uses Throw or Abort in its initialization cannot be auto-loaded? $\endgroup$ – Szabolcs May 12 '16 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 May 12 '16 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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