I'm not sure I fully understand this.
Making one action, in this case sending an AT command to an external device, dependent on the results of a previous operation is quite a reasonable thing to do. If a failure is detected for example with the initialisation, then it is not useful to proceed to send the following commands.
Neither do I believe that spaghetti code is a inevitable consequence of attempting to solve this. A state machine approach could provide an elegant solution here. If required, some of the state transitions could have a timing element to allow, for example, a serial buffer to fill.