Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elm-analyse fails with Cannot find module error. #218

Open
akhilman opened this issue Oct 20, 2019 · 16 comments
Open

Elm-analyse fails with Cannot find module error. #218

akhilman opened this issue Oct 20, 2019 · 16 comments

Comments

@akhilman
Copy link

I have a project with the code from Elm’s tutorial.
Code itself compiles and works great, elm-format also works well. But elm-language-server and elm-analyse fails with same error:

`--> elm-analyse src/Main.elm
Fetching package information from package.elm-lang.org.
Fetched dependencies
INFO: Started...
INFO: No configuration provided. Using default configuration.
INFO: Load dependency elm/browser 1.0.1
internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module '/home/ildar/Projects/learning-elm/test/elm-stuff/packages/elm/browser/1.0.1/elm.json'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.getDependencyFiles (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/util/file-gatherer.js:63:26)
    at Array.<anonymous> (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/ports/dependency-files.js:13:35)
    at Function.f (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/backend-elm.js:2170:19)
    at A3 (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/backend-elm.js:59:28)
    at Object.b (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/backend-elm.js:1974:7)
    at _Scheduler_step (/home/ildar/.config/yarn/global/node_modules/elm-analyse/dist/app/backend-elm.js:1818:20)

As I figured out all modules located in local cache inside ~/elm directory. How I can make elm-analyse load modules form local cache?

Environment:
installed globally with yarn

  • elm@0.19.0-no-deps
  • @elm-tooling/elm-language-server@1.4.1
  • elm-analyse@0.16.4
  • elm-format@0.8.2
    installed with system package manager
  • node v10.16.3
@antew
Copy link
Contributor

antew commented Oct 21, 2019

It looks like it is failing in the test directory, does the elm.json in there have elm/browser listed as a dependency in it?

@akhilman
Copy link
Author

Yes elm/browser is listed in elm.json
Here is a content from my elm.json:

{
    "type": "application",
    "source-directories": [
        "src"
    ],
    "elm-version": "0.19.0",
    "dependencies": {
        "direct": {
            "elm/browser": "1.0.1",
            "elm/core": "1.0.2",
            "elm/html": "1.0.0"
        },
        "indirect": {
            "elm/json": "1.1.3",
            "elm/time": "1.0.0",
            "elm/url": "1.0.0",
            "elm/virtual-dom": "1.0.2"
        }
    },
    "test-dependencies": {
        "direct": {},
        "indirect": {}
    }
}

And here is list of all files I have in my project:

.:
elm.json
elm-stuff
index.html
src

./elm-stuff:
0.19.0

./elm-stuff/0.19.0:
Main.elmi
Main.elmo
summary.dat

./src:
Main.elm

@ValeTheVioletMote
Copy link

ValeTheVioletMote commented Jan 22, 2020

I'm having the same problem. Fresh install, basic project made from the tutorial.

I'm on Windows 10.

Where/why/how is it expecting to get these files?

elm-stuff/packages/elm/core/1.0.4/elm.json
elm-stuff/packages/elm/json/1.1.3/elm.json
elm-stuff/packages/elm/html/1.0.0/elm.json
elm-stuff/packages/elm/http/2.0.0/elm.json

Is it trying to download? Does it need proxy setup?

@ValeTheVioletMote
Copy link

It looks like...

In elm-analyse\dist\app\util\file-gatherer.js

function getDependencyFiles(directory, dep) {
    var depPath = directory + "/elm-stuff/packages/" + dep.name + "/" + dep.version;
    var depPackageFile = require(depPath + '/elm.json');
    var unfilteredTargetFiles = targetFilesForPathAndPackage(directory, depPath, depPackageFile);
    var exposedModules = depPackageFile['exposed-modules'].map(function (x) {
        return _path.normalize('/' + x.replace(new RegExp('\\.', 'g'), '/') + '.elm');
    });
    return unfilteredTargetFiles.filter(function (x) {
        return exposedModules.filter(function (e) { return lodash_1.default.endsWith(x, e); })[0];
    });
}

Instead of grabbing from %appdata%/elm/0.19.1/packages it's assuming that the elm-stuff folder will have its own copy for some reason?

I'll try overriding this.

@ValeTheVioletMote
Copy link

So now with a shimmy:

function getDependencyFiles(directory, dep) {
    var elm_version = "0.19.1"; // <-- this is really bad
    var depPath = process.env.APPDATA + "/elm/"+elm_version+"/packages/" + dep.name + "/" + dep.version; // directory var useless
    var depPackageFile = require(depPath + '/elm.json');
    var unfilteredTargetFiles = targetFilesForPathAndPackage(directory, depPath, depPackageFile);
    var exposedModules = depPackageFile['exposed-modules'].map(function (x) {
        return _path.normalize('/' + x.replace(new RegExp('\\.', 'g'), '/') + '.elm');
    });
    return unfilteredTargetFiles.filter(function (x) {
        return exposedModules.filter(function (e) { return lodash_1.default.endsWith(x, e); })[0];
    });
}

I get:
TypeError: depPackageFile.exposed-modules.map is not a function

Which makes sense, because you can't use .map on an object, which 'exposed-modules' most definitely is:

"exposed-modules": {
        "Primitives": [
            "Basics",
            "String",
            "Char",
            "Bitwise",
            "Tuple"
        ],
        "Collections": [
            "List",
            "Dict",
            "Set",
            "Array"
        ],
        "Error Handling": [
            "Maybe",
            "Result"
        ],
        "Debug": [
            "Debug"
        ],
        "Effects": [
            "Platform.Cmd",
            "Platform.Sub",
            "Platform",
            "Process",
            "Task"
        ]
    }

Is elm-analyse far too outdated for elm 0.19? It's expecting an array where an object lives now.

@antew
Copy link
Contributor

antew commented Jan 22, 2020

Anyone have a repo that reproduces this issue?

Elm Analyse does work with 0.19, we use 0.19.1 in the project at work and it is working in there.

@ValeTheVioletMote
Copy link

On my home machine now. Works just fine there. Of note, getDependencyFiles doesn't even appear to ever be called on this setup.

So a hunt for what logic calls gDF might help us track it down.

@ValeTheVioletMote
Copy link

More accurately, seems to be something to do with loadDependencyFiles. I'm not proficient in Elm whatsoever but I'll try to see how it's called.

@akhilman
Copy link
Author

https://github.com/akhilman/elm-counter - repository that causes error for me.

@ValeTheVioletMote
Copy link

I don't even need a Main.elm @akhilman Are you behind a proxy?

Looking at this... (src/Analyser/Files/DependencyLoader.elm) :

        OnOnlineDocs result ->
            case result of
                Nothing ->
                    ( model, Cmd.none )

                Just (Err _) ->
                    ( { model | state = RawDiskLoading }
                    , DependencyHandler.loadDependencyFiles model.dependency
                    )

                Just (Ok decodedDependency) ->
                    ( { model | state = Done decodedDependency }
                    , Cmd.batch
                        [ DependencyHandler.storeToDisk decodedDependency
                        , Logger.info ("Loaded " ++ model.dependency.name ++ " from package.elm-lang.org")
                        ]
                    )

Here's my guess... When OnOnlineDocs has a result of Err _, it fires off loadDependencyFiles -> getDependencyFiles -> our crash.

Looks like the idea is, "If we can't get the docs online, grab them offline from the ones we already got." Seems to miss the case where you can't grab docs online BEFORE you could ever get them in the first place, resulting in our exception.

What causes OnOnlineDocs to have a failure? I'm going to guess it might be trying to download something, as I first theorized, and for my machine behind an incredibly finnicky proxy at least, that may be causing it to fail.

I'll keep looking. Slowly. I am trying to learn Elm and got snagged here while doing the tutorial. Guess this is a crash course.. :)

@akhilman
Copy link
Author

I don't even need a Main.elm @akhilman Are you behind a proxy?

No. I'm not. But here in Russia we have a lot of IP banned and elm may hit some of them.

@ValeTheVioletMote
Copy link

DependencyLoader init -> DependencyHandler.readFromDisk -> Failed -> DependencyHandler.loadOnlineDocumentation --> ?

but I can't get much further here. I don't understand what occurs in what order:

-- This.. (loadOnlineDocumentation)?
Failed ->
                    ( { model | state = LoadingOnlineDocs }
                    , DependencyHandler.loadOnlineDocumentation model.dependency
                    )

-- Or this (onOnlineDocumentation)?
LoadingOnlineDocs ->
            DependencyHandler.onOnlineDocumentation model.dependency
                |> Sub.map OnOnlineDocs

I presume once the state is changed, the latter piece is fired. But why does it seem to be doing the same work as the former? Or is the latter only called on init..??

The latter is what causes our error, presumably, so why is it favored over the former? Or what's the purpose of the former? Very confusing.

Or is the former what loads the docs, which then triggers onOnlineDocumentation, which then triggers Sub.map OnlineDocs...? I can't tell. Don't know the lang well enough.

@akhilman our best lead is that it has something to do with a network problem, then.

@antew could you help me understand this code when you have some time?

I'll try to see if I can replicate this in a docker container after routing online docs to localhost or something.

@ValeTheVioletMote
Copy link

ValeTheVioletMote commented Jan 23, 2020

CONFIRMED.

docker run -it debian /bin/bash

apt update -y && apt install curl npm -y
npm install -g npm
cd ~/ && curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz
gzip -d elm.gz
chmod +x elm
mv elm /usr/local/bin/
mkdir elmproj && cd elmproj/
elm init
npm install -g elm-analyse
echo "172.0.0.1 package.elm-lang.org elm-lang.org" >> /etc/hosts
elm-analyse

Replicates the exception on a 'normal' system. See:

Fetching package information from package.elm-lang.org.
Fetched dependencies
INFO: Started...
INFO: No configuration provided. Using default configuration.
INFO: Load dependency elm/html 1.0.0
INFO: Load dependency elm/core 1.0.4
INFO: Load dependency elm/browser 1.0.2
internal/modules/cjs/loader.js:583
    throw err;
    ^

Error: Cannot find module '/root/elmproj/elm-stuff/packages/elm/core/1.0.4/elm.json'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.Module._load (internal/modules/cjs/loader.js:507:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.getDependencyFiles (/usr/local/lib/node_modules/elm-analyse/dist/app/util/file-gatherer.js:63:26)
    at Array.<anonymous> (/usr/local/lib/node_modules/elm-analyse/dist/app/ports/dependency-files.js:13:35)
    at Function.f (/usr/local/lib/node_modules/elm-analyse/dist/app/backend-elm.js:2174:19)
    at A3 (/usr/local/lib/node_modules/elm-analyse/dist/app/backend-elm.js:59:28)
    at Object.b (/usr/local/lib/node_modules/elm-analyse/dist/app/backend-elm.js:1978:7)
    at _Scheduler_step (/usr/local/lib/node_modules/elm-analyse/dist/app/backend-elm.js:1822:20)

I cause an error with a timeout here. I think on my work computer, it's an SSL or proxy error. You match Err _ so it takes 'em all.

Also worth noting is that you get no info about the package info failing to fetch.

@akhilman
Copy link
Author

Also found aliases in my shell settings that was added when package.elm-lang.org was blacklisted:
elm => env http_proxy=elm.dmy.fr:9999 elm
elm-analyse => env http_proxy=elm.dmy.fr:9999 elm-analyse

Today package.elm-lang.org can be accessed without proxy.
Without aliases all works fine.

@ValeTheVioletMote
Copy link

ValeTheVioletMote commented Jan 23, 2020

I can get it to perform correctly at work if I set HTTP_PROXY, HTTPS_PROXY, and NODE_TLS_REJECT_UNAUTHORIZED=0.

Now getting VSCode to do that for the tooling is a different matter altogether.....

Looks like my workaround for now will be to run elm-analyse manually, restart VSCode, and then do that again whenever I have new packages.

@ValeTheVioletMote
Copy link

At the very least, I would suggest that

        OnOnlineDocs result ->
            case result of
                Nothing ->
                    ( model, Cmd.none )

                Just (Err _) ->
                    ( { model | state = RawDiskLoading }
                    , DependencyHandler.loadDependencyFiles model.dependency
                    )

Be changed such that the network error underlying it all is logged to the console.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants