From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 0162A138010 for ; Sat, 20 Oct 2012 18:17:24 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id E9B5321C073; Sat, 20 Oct 2012 18:17:11 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id E8E0721C046 for ; Sat, 20 Oct 2012 18:16:34 +0000 (UTC) Received: from [192.168.26.5] (ip98-164-193-252.oc.oc.cox.net [98.164.193.252]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: zmedico) by smtp.gentoo.org (Postfix) with ESMTPSA id 34EE133D7CE for ; Sat, 20 Oct 2012 18:16:34 +0000 (UTC) Message-ID: <5082EA80.6030206@gentoo.org> Date: Sat, 20 Oct 2012 11:16:32 -0700 From: Zac Medico User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:15.0) Gecko/20121012 Thunderbird/15.0.1 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org MIME-Version: 1.0 To: gentoo-dev@lists.gentoo.org Subject: Re: [gentoo-dev] eclass error-handling post-EAPI4 References: <5081627B.1040707@malth.us> <50816DB7.4070602@gentoo.org> <50828281.6030101@malth.us> In-Reply-To: <50828281.6030101@malth.us> X-Enigmail-Version: 1.4.4 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Archives-Salt: 033840c6-ff2c-4c56-8335-32e9ddee3c5c X-Archives-Hash: 24dc25a80866cf0f0e882cc89dd25701 On 10/20/2012 03:52 AM, Gregory M. Turner wrote: > If I indeed understand the facts correctly, I'm still a bit > uncomfortable with your advice to just use "helper || die" in eclass > code. It seems to me that if I follow this recipe, >=EAPI4 kinda works > OK, but EAPI[0-3] doesn't. > > Specifically, an EAPI[0-3] ebuild author will not have any means at his > or her disposal to handle errors that occur in eclass utility functions. > The error-handling semantics of eclass utility functions would be like > EAPI4, except without nonfatal around to provide relief from auto-die. > > EAPI[0-3] conventions encourage the habit of writing ebuild code like > normal bash script code, which is to say, that authors expect to be able > to write code like > > invoke_fn || ... # handle error, probably by die()ing but maybe not > > But eclasses that auto-die violate this expectation and create a > situation where ebuild authors must be mindful of whether a particular > function is a helper-function or an eclass utility function to correctly > anticipate whether auto-death will occur. > > This seems to be by design and may not be so horrible as I make it sound > -- for example, it would be pretty weird to expect eclass code written > before EAPI4 to suddenly start working differently in EAPI[0-3]. > > But should we really write new eclass code to behave this way as well? Yeah, I think we should. If the eclass function is doing something that might result in an undesirable die, then it can try to avoid the die by first doing a sanity check. For example, it can check that a given file path exists before passing it to the helper, and skip calling the helper if the file path doesn't exist. > Worse, eclasses authored in the pre-EAPI4 era ubiquitously assume that > die() never returns, and do things like: > > efoo() { > [[ ${EBUILD_PHASE} != "prepare" ]] && > die "efoo can only be used during src_prepare" > . > . > # stuff that isn't safe if ${EBUILD_PHASE} != "prepare" > . > . > } > > Since, in EAPI4, no means is provided to specify that a particular > invocation of die() is unconditionally terminal, (except directly > manipulating PORTAGE_NONFATAL, which doesn't seem to be encouraged), the > only non-encapsulation-breaking non-EAPI-specific solution would be to > re-code every presumed-terminal use of die() to look something like: > > failure_prone_action > ret=$? > if [[ ${ret} != 0 ]] ; then > die "Error message" > return ${ret} > fi > > I can imagine no reasonable way to avoid this without using aliases... > or perhaps some construct like: > > do_or_die() { > diemsg="$1" > shift > "$@" || { ret=$?; die "${diemsg}"; return ${ret}; } > } > > efoo() { > do_or_die "error message 1" \ > failure_prone_action1 arg1 arg2 arg3 && \ > safe_action1 arg1 && \ > safe_action2 arg1 arg2 && \ > do_or_die "error message 2" \ > failure_prone_action2 arg1 arg2 && \ > . > . > > Hopefully I'm missing something here...? I never really liked the nonfatal helper. If you don't want a helper to die, then I'd suggest to use sanity checks before calling the helper, and avoid calling the helper if it seems like it will trigger an unwanted die. -- Thanks, Zac