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

Different exit codes for different failure types #2220

Open
ekalin opened this issue Mar 22, 2024 · 4 comments · Fixed by #2243
Open

Different exit codes for different failure types #2220

ekalin opened this issue Mar 22, 2024 · 4 comments · Fixed by #2243
Labels
feature suggestion Feature suggestion

Comments

@ekalin
Copy link
Collaborator

ekalin commented Mar 22, 2024

Provide us a use case of the feature
I believe instaloader should exit with a non-zero exit code in case of failure. This has been requested already (#1614) and there is even a PR for this (#2166). However, I believe that not only a non-zero exit code should be used, but different codes should be used for different failures.

Describe the solution you'd like
I thought of something like
0 - Finished normally
1 - Initialization failure: invalid command line arguments, --load-cookies without the library, and other failures before anything was attempted
2 - Login failure
3 - Failure while downloading
4 - User aborted (I'm not sure if this is an error - after all, the user requested the action. But it might be useful to distinguish this case)

Maybe there could be a couple more situations. But too much granularity might make this feature less useful.

Describe alternatives you've considered
There really aren't many alternatives. One can try parsing the output, but there are too many possible error messages.

If the feature request is accepted, would you be willing to submit a pull request?
Yes

@aandergr
Copy link
Member

Yes, this would be a nice feature.

I was wondering whether there was some kind of standard or convention for how exit codes are assigned in typical unix applications, but it seems there is none except of zero being a success status and non-zero an error status. Apart of that, all tools seem to follow their arbitrary mapping of error types to exit codes.

Instaloader already distinguishes many types of errors with different exception types, it would be great to map those into return codes for the cli application. We could somehow resemble the exception tree, combined with some semantical/logical grouping of error types into the error code, e.g. by assigning a few bits to the group and the other bits to a finer granulation, as this might simplify the parsing of the exit status. So we would both have a fine granularity without making the feature less useful I think.

I could imagine something like

code Meaning
0x01 InvalidArgumentException, invalid command line arguments, --load-cookies without the library, and other failures before anything was attempted (which are currently returned with a simply SystemExit before an Instaloader instance is created)
0x10 Other connection error
0x11 Query returned "not found"
0x12 Too many requests
0x21 Query returned "bad request"
0x22 Query returned "forbidden"
0x23 Profile not exists
0x24 Private profile not followed
0x25 Login required
0x26 IPhoneSupportDisabledException
0x41 Two factor auth required
0x42 Bad credentials
0x81 User aborted (--abort-on)
0x82 User aborted (SIGINT / control+c)

So this would imply a grouping of

code & 0xf0 Meaning of group
0x00 Invalid invocation, before anything was attempted
0x10 Invocation was correct, however Instaloader failed to download
0x20 Download of the target impossible with the given invocation
0x40 Login error
0x80 User aborted

This is close to the grouping given by the exception tree, which itself was built on the way of how they must be handled internally.

However, this is only a suggestion after brief consideration. I do not want to rule out the possibility that there might be a more sensible or appropriate mapping.

@ekalin
Copy link
Collaborator Author

ekalin commented Mar 29, 2024

I think too many exit codes would actually add too much complexity for little benefit. If the user needs that much detail, they can use instaloader as a module and catch the actual exceptions.

[Moreover, retrofitting the exit codes in the existing code is not trivial - and the more different codes there are, the more work is necessary.]

But in addition to the general categories I had identified, some of the ones you listed can be useful:

  • Too many requests - I'd say this one deserves its own error code. However, from what I remember, if a 429 is received, the program just waits and then retries, indefinitely. It does not abort the program, unless --abort-on is used.
  • Login required - Probably useful
  • Profile does not exists / is private - Could be useful. Would be more a warning than an error, since just one of many profiles could have failed. On the on other hand, some users occasionally make their profile private (or disable them) temporarily, and I'm not sure I need to mark a instaloader run as 'failed' just because of that.

Basically your idea of groups is quite similar to my proposal, but I'm not really convinced that the level of detail provided by the lower byte is really useful. And from what I remember, some errors you listed ("bad request", "forbidden", etc) don't cause the program to terminate, just to retry or skip that item.

@aandergr
Copy link
Member

aandergr commented May 4, 2024

I think too many exit codes would actually add too much complexity for little benefit. If the user needs that much detail, they can use instaloader as a module and catch the actual exceptions.

I think, this is a very convincing point.

I also agree that my suggested mapping from exceptions to error codes is not at all practical as is, since almost all exceptions are handled internally and do not directly lead to a termination.

Would be more a warning than an error, since just one of many profiles could have failed.

If one of many profiles have failed, Instaloader should probably return a non-zero exit code to indicate there was a failure. This however means that multiple different failures may have happened (and handled) during the download loop, narrowing down the number of exit codes that we can return.

All in all it seems we might agree on the following return codes:

code Meaning
0 Finished normally
1 Initialization failure: invalid command line arguments, --load-cookies without the library, and other failures before anything was attempted, e.g. flags that require login without --login
2 Login failure
3 Failure while downloading (e.g. profile does not exist)
4 User aborted (--abort-on)
5 User aborted (SIGINT / control+c)

@ekalin
Copy link
Collaborator Author

ekalin commented May 5, 2024

This set of codes looks good, but I'd like to propose a small change:

0 Finished normally
1 Failure while downloading (e.g. profile does not exist)
2 Initialization failure: invalid command line arguments, --load-cookies without the library, and other failures before anything was attempted, e.g. flags that require login without --login
3 Login failure
4 User aborted (--abort-on)
5 User aborted (SIGINT / control+c)

The reason is that argparse returns 2 when an error while parsing the command line is found. It's possible to change this easily only in Python 3.9+, so it seems easier to make later initialization failures also return 2.

Since what was proposed as exit code 3 can be a non-fatal error (one profile failed, but other might have succeeded), I think it's a good fit for error code 1.

Alternatively, we could just one use exit code 1, there's nothing saying the error codes have to be sequential and that all values must be used.

@aandergr aandergr linked a pull request May 12, 2024 that will close this issue
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature suggestion Feature suggestion
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants