google/vim-maktaba

Odd behaviour with :silent! call maktaba#plugin#Detect()

malcolmr opened this issue · 2 comments

This may not really be a Maktaba problem at all, but it's odd nonetheless.

Given the following .vimrc, and Vim 7.4.922:

set nocompatible
set rtp=foo,foo.vim,bar
source maktaba/bootstrap.vim

(The &rtp directories don't need to exist.)

Run Vim with vim -u vimrc and then run :silent! call maktaba#plugin#Detect(), and the result is:

Error detected while processing function maktaba#plugin#Detect[2]..maktaba#plugin#GetOrInstall[18]..<SNR>4_CreatePluginObject[31]..maktaba#plugin#AddonInfo:
line    8:
E484: Can't open file bar/addon-info.json

Error detected while processing function maktaba#plugin#Detect[2]..maktaba#plugin#GetOrInstall[18]..<SNR>4_CreatePluginObject[31]..maktaba#plugin#AddonInfo[8]..<SNR>4_EvalJSON:
line    8:
E15: Invalid expression: 
E15: Invalid expression: 

The weird part here is the first error (and in the real situation that prompted this report, that's all we see); it makes no sense to see an E484 from maktaba#plugin#AddonInfo(), since it surrounds everything with a try..catch /E48[45]:/.

Running without :silent! shows the real problem:

Error detected while processing function maktaba#plugin#Detect[2]..maktaba#plugin#GetOrInstall:
line   11:
E605: Exception not caught: ERROR(AlreadyExists): Conflict for plugin "foo": foo/ and foo.vim/

Error detected while processing function maktaba#plugin#Detect:
line    2:
E170: Missing :endfor

It seems wrong that calling with :silent! causes a different exception to be reported (or be reported at all, given that :silent! is supposed to suppress them). Is this just an artifact of how Vim's exception handling works, or is Maktaba doing something wrong?

(The real code I'm looking at is calling maktaba#plugin#RegisteredPlugins() in the context of a :silent! call in order to track plugin usage.)

Minimal repro:

function ThrowBoom() abort
  throw 'BOOM'
endfunction

function ReproNotReallySilent() abort
  call ThrowBoom()
  try
    call join(1)
  catch /E714:/
  endtry
endfunction

:silent! call ReproNotReallySilent()

The docs on error handling (like :h except-compat) are really confusing, but seem to say that :silent! makes it continue execution after errors (even with abort functions?). We could file a bug in the vim tracker to ask if it's intended behavior.

Raised as vim/vim#538. Bizarrely it seems that the behaviour of :silent! is as we expect when an exception is thrown from a builtin function, just not when it's thrown from :throw.