If you're open to a sliiiightly different approach, may I heartily recommend use-package? Rather than "attempt to use, check for error, install if error,"
use-package will, on first install, check if the package exists at all and install it if needed. It's also effectively a deferred
require, which can be very nice for managing package existence without bogging down loading.
This does, of course, mean you have to be sure
use-package is installed properly, but the up-side is you only have to manually ensure a single package. I do this as @Tobias suggested, with an addition:
;; Be sure we've fetched the package archive at least once before
;; attempting to install anything.
;; Manually check for `use-package`, install if needed
(unless (package-installed-p 'use-package)
Do note: in the case of
auctex specifically, the
use-package declaration takes a particular form:
This is due to an idiosyncracy of
auctex itself; see this question and very thorough answer for details.