AriaMinaei/pretty-error

Question: How can I replace the fullPath to the app directory by an alias

Closed this issue · 8 comments

AoDev commented

Hi,

I just discovered your module, which is really nice for mental sanity when looking at errors! Thank you.

I see that for node modules paths (dependencies), by default, the full path to the app root directory has an alias. Something like "[name-of-the-app]"

But this is not the case for the app code itself. How can we do the same for any path?

Hi,

Yeah, you can use the alias() method described here.

AoDev commented

Hi, I have done that but it's not very robust because people won't have the same install path usually.

I used a regex but it could happen that the regex matches something that it should not for another developer.

I think that having an option like aliasRootPath would be nice and would output the same thing than for the node_modules in the dependencies.

I thought about that when first publishing PE, but I couldn't come up with a good definition for rootPath. I mean, what's the algorithm that's supposed to detect the rootPath?

Suppose we're running our code using this command:

$ node /path/to/project/lib/foo/bar.js

... and we want PE to detect that the path to the project root is /path/to/project/.

How are we gonna do that?

Should we get the path to the main module? No, that's /path/to/project/lib/foo/. We'd be off by two subdirs.
Can we use process.cwd? Not necessarily.
Can we use the dirname() of the module that require()ed PE? Well, that module could be anywhere, like /path/to/project/lib/foo/bar/baz.js. We'd be off by three subdirs.

We could, perhaps use the path to the main module (/path/to/project/lib/foo/bar.js) and then traverse up until we find a package.json file. But that just seems like an overkill, don't you think?

AoDev commented

I don't understand, I thought PE was doing it already.

Here is a stack trace with pretty error.

You can see that the fullpath to the app directory is aliased as "[APP-ROOT-DIR]" when the call/path is from a node module dependency. (under APP-ROOT-DIR/node_modules)

(I replaced the real name)

But, when the path is somewhere else like in one of the lines:

`/Users/myUserName/git-repos/diverse/APP-ROOT-DIR/modules/account/Auth.js:436:14``

It does not do it. But I believe there is no difference if the call was under ROOT/node_modules or ROOT/other_dir. The behaviour should be the same.

Error: Multipart: Boundary not found

  - multipart.js:58 new Multipart
    [APP-ROOT-DIR]/[multer]/[busboy]/lib/types/multipart.js:58:11

  - multipart.js:26 Multipart
    [APP-ROOT-DIR]/[multer]/[busboy]/lib/types/multipart.js:26:12

  - main.js:62 Busboy.parseHeaders
    [APP-ROOT-DIR]/[multer]/[busboy]/lib/main.js:62:22

  - main.js:21 new Busboy
    [APP-ROOT-DIR]/[multer]/[busboy]/lib/main.js:21:10

  - index.js:54
    [APP-ROOT-DIR]/[multer]/index.js:54:20

  - layer.js:82 Layer.handle [as handle_request]
    [APP-ROOT-DIR]/[express]/lib/router/layer.js:82:5

  - route.js:110 next
    [APP-ROOT-DIR]/[express]/lib/router/route.js:110:13

  - Auth.js:436
    /Users/myUserName/git-repos/diverse/APP-ROOT-DIR/modules/account/Auth.js:436:14

  - Auth.js:587
    /Users/myUserName/git-repos/diverse/APP-ROOT-DIR/modules/account/Auth.js:587:14

  - index.js:137 Query._callback
    /Users/myUserName/git-repos/diverse/APP-ROOT-DIR/db/index.js:137:7

  - Sequence.js:96 Query.Sequence.end
    [APP-ROOT-DIR]/[mysql]/lib/protocol/sequences/Sequence.js:96:24

  - Query.js:144 Query._handleFinalResultPacket
    [APP-ROOT-DIR]/[mysql]/lib/protocol/sequences/Query.js:144:8

  - Query.js:128 Query.EofPacket
    [APP-ROOT-DIR]/[mysql]/lib/protocol/sequences/Query.js:128:8

  - Protocol.js:271 Protocol._parsePacket
    [APP-ROOT-DIR]/[mysql]/lib/protocol/Protocol.js:271:23

  - Parser.js:77 Parser.write
    [APP-ROOT-DIR]/[mysql]/lib/protocol/Parser.js:77:12

  - Protocol.js:39 Protocol.write

You're right. When PE sees the first /node_modules/ in a trace line, it can shorten the path that comes before it. If it can't find that name though, it leaves the path unchanged.

I see that this gives two different behaviors that are inconsistent with each other. We can fix it by running a single pass of all the trace lines, and if one of them finds the app root, we can use that path for all the other trace lines. But that will still give us inconsistent behavior if an error doesn't have a trace line in any of the files inside /node_modules/...

Ideas?

AoDev commented

I think that you could use this /node_modules path to fix the other strings.
OR/AND if there is none, it can be done by comparing two paths, and finding the common "prefix".

There is this module for example: https://www.npmjs.com/package/commondir

Could we assume that all the calls will be under the same root? so two paths to compare is enough. Or could there be some other cases where it would somehow call something from another place like a global module?

I don't know about performance issue.

Hey @AoDev, sorry for the long delay. All the solutions that we discussed seem to be non-deterministic. They can't guess the root folder in all cases. For example, what if we're running our code in a test-runner? We certainly don't want mocha's root dir to be chosen as the main project's root dir.

The easier option would be for the dev to supply the root dir herself using PE::alias().

I also think that I should remove the logic that shortens the path in some cases and doesn't shorten it in other cases. It's non-deterministic and confusing.

Closing since this issue has been inactive. Feel free to re-open if you think this needs more attention.