niieani / bash-oo-framework

Bash Infinity is a modern standard library / framework / boilerplate for Bash
https://github.com/niieani/bash-oo-framework/discussions
MIT License
5.57k stars 247 forks source link

[bug?] `throw` is said to be 'undefined command' when `import` fail #66

Open Cj-bc opened 6 years ago

Cj-bc commented 6 years ago

Commit hash: 903fd74

While I tried importing my script, this error has been occurred:

 ✘ UNCAUGHT EXCEPTION: Undefined command (throw)
    ➦ Undefined command [oo-bootstrap.sh:84]
    ✘ System::SourcePath "${__oo__path}/${libPath}" "$@" || e="Cannot import $libPath" throw [oo-bootstrap.sh:84]                                                                                         
       ➦ System::ImportOne "$libPath" [oo-bootstrap.sh:96]
          ➦ System::Import [laun.sh:9]
          ✘ import launsh_lib/keys [laun.sh:9]

( launsh.sh and launsh_lib/* is mine)

From my research, I figured out that throw was treated as exit_code in command_not_found_handle:

# piece of result of 'bash -x laun.sh`
+(oo-bootstrap.sh:89): System::ImportOne(): throw
+(exception.sh:30): command_not_found_handle(): local 'IFS=
'
+(exception.sh:33): command_not_found_handle(): [[ throw = \(\ \s\e\t\ \-*\;\ \t\r\u\e* ]]
+(exception.sh:38): command_not_found_handle(): Exception::CustomCommandHandler throw
+(exception.sh:17): Exception::CustomCommandHandler(): return 1
+(exception.sh:38): command_not_found_handle(): true
+(exception.sh:40): command_not_found_handle(): local exit_code=throw

It's strange because exit_code should be $1, not ${FUNCNAME[0]}. In this time, exit_code should be empty. Source: https://github.com/niieani/bash-oo-framework/blob/903fd74533631c9e46a7554833f494838f645731/lib/util/exception.sh#L40

Actually, this is strange too: https://github.com/niieani/bash-oo-framework/blob/903fd74533631c9e46a7554833f494838f645731/lib/util/exception.sh#L33 (because $* is expanded to throw)


Unfortunately, I have no idea to solve this, so I post it.

the minimum example code:

#!/usr/bin/env bash                                                                                                                                                                                         

source "$( cd "${BASH_SOURCE[0]%/*}" && pwd )/lib/oo-bootstrap.sh"

import util/log util/exception
import file_not_exist  # try to import non-exist file

echo 'hello!'
Cj-bc commented 6 years ago

I tryed some, so report them.

For all of below codes, I modified util/exception.sh a little bit:

  28 command_not_found_handle() {
+ 29   echo $@
  30   # USE DEFAULT IFS IN CASE IT WAS CHANGED
  31   local IFS=$' \t\n'
  32
  1. change throw alias to pass $1 to command_not_found_handle

Purpose: To check whether $1 will be passed to command_not_found_handle Result: the argunment was not passed as $1

Tried to check whether alias is the problem:

# modified code: in util/exception.sh
alias throw="__EXCEPTION_TYPE__=\${e:-Manually invoked} command_not_found_handle hoge"

# my script is the same one as above
# outputs
throw

 ✘ UNCAUGHT EXCEPTION: Undefined command (throw)
    ➦ Undefined command [oo-bootstrap.sh:84]
    ✘ System::SourcePath "${__oo__path}/${libPath}" "$@" || e="Cannot import $libPath" throw [oo-bootstrap.sh:84]
       ➦ System::ImportOne "$libPath" [oo-bootstrap.sh:96]
          ➦ System::Import [command_not_found_handle_test.sh:3]
          ✘ import file_not_exist [command_not_found_handle_test.sh:3]

 ⚡ Press [CTRL+C] to exit or [Return] to continue execution.

hoge, which was pessed as $1 is not shown as one of the $@.

I have no idea what's happen here...omg (I searched if there're other definitions for throw and command_not_found_handle, but I couldn't find anymore than I know.)(searched by using git grep)

  1. call throw manually from my script

Purpose: To check whether throw works correctly in other cases Result: It worked

It seems that throw works fine for manually executing.

I tested to call throw by myself in my test script:

import util/exception util/log util/tryCatch

  e="hello. test" throw "this is just atest"

then outputs:

 ✘ UNCAUGHT EXCEPTION: hello. test (this is just atest)
    e="➦ hello. test" throw "this is just atest" [command_not_found_handle_test.sh:9]

 ⚡ Press [CTRL+C] to exit or [Return] to continue execution.
⚙  Continuing...

3.1 call throw from my function

Purpose: To check whether function do something bad Result: It worked

Call throw in my function

# my script
import util/exception util/log util/tryCatch

testfunc() {
  e="hello. test" throw "this is just atest"
}
testfunc

#
# outputs
this is just atest

 ✘ UNCAUGHT EXCEPTION: hello. test (hoge)
    e="hello. test" throw "➦ this is just atest" [command_not_found_handle_test.sh:13]
       ➦ testfunc [command_not_found_handle_test.sh:16]

 ⚡ Press [CTRL+C] to exit or [Return] to continue execution.

3.2 call throw from my function. excecute the function using alias

Purpose: To check whether alias do something bad Result: It worked

Using testfunc in 3.1, but call it using alias

# my script
import util/exception util/log util/tryCatch

testfunc() {
  e="hello. test" throw "this is just atest"
}

alias ali="testfunc"
ali

# outputs
this is just atest

 ✘ UNCAUGHT EXCEPTION: hello. test (this is just atest)
    e="➦ hello. test" throw "this is just atest" [command_not_found_handle_test.sh:13]
       alias ali="➦ testfunc" [command_not_found_handle_test.sh:16]

 ⚡ Press [CTRL+C] to exit or [Return] to continue execution.
⚙  Continuing...
Cj-bc commented 6 years ago

sorry, this is not a bug of this framework, probably. I tried with a simple snipet which does not use oo- framework and got the same result. As I'm away from my PC, I'll post the code later.

Cj-bc commented 6 years ago

Here's the code!!

#!/usr/bin/env bash

alias test_a="command_not_found_handle"

command_not_found_handle() {
echo $*
}

test_a # call function using alias
echo '----'
command_not_found_handle # call function directly

and here's outputs:

$?is0[bugfix/throw-puts-wrong-exception]
<X_X>:bash-oo-framework$ ./test_throw_bug.sh # the above code
test_a
----

$?is0[bugfix/throw-puts-wrong-exception]
niieani commented 6 years ago

It seems like a bash bug: even when the alias throw is declared at the very beginning, it seems unavailable within the body of the System::ImportOne function.

We can think about a good solution when planning for #45.

Cj-bc commented 6 years ago

I sent a bug-report to bash by using bashbug. I hope this will be fixed someday...

If I find good solution, I'll post it to #45

And... Should we close this issue?