[SalesForce] How to show user a message and stop APEX Class execution

I have a APEX Class that runs from a button on a standard record page. It creates a related record in another table. The code works fine as it is now.

But I want to add a feature that does a check (Selection Field == Value) and if the check fails the user is given a custom message and the code stops running, and no record gets created. I can't figure this out.

I have run across such functions as 'adderror' and 'addmessages', but not sure how to get these working. This starts from a button press on the starting page,
the record is created and then the user is taken to the records page. If there is no record to be created then there is no page to go to. Can I put the error message back onto the starting page? But would it not need to be refreshed to show the error, and then won't the error status be lost? Or do I need to create a new VF page that is just a spot holder for the error? If error, then VF page and show error, if not then normal process? I was hoping I could do a simple 'alert', but that doesn't work.

Any pointers would help here, not sure what I need to do to get this working.

Best Answer

I think you answer your own question. When we make buttons record detail pages we never have the button do any of the work via javascript. The button simply redirects to a blank VF page. This is pattern is especially important because Lightning does not support javascript buttons for security reasons. This approach is supported in Lightning.

/Apex/custompage?oppId=XXXXXXXXXXXXXXX

The Page contains an "init" method that is added to the pages "action" attribute:

<apex:page standardController="Opportunity" extensions="oppExtension" action="{!init}">
    <apex:pageMessages/>
    <!-- optional go back link -->
</apex:page>

If there is a failure, you can catch it and use the AddMessages method to display something to your user, otherwise, redirect the user to the new record page.

public class oppExtension {
    public PageReference init() {
        PageReference result;

        // get url params
        Id oppId = ApexPages.getParameters().get('oppId');
        String retURL = ApexPages.getParamters().get('retURL'); // Option param for go-back link functionality

        // do tha thing
        if (thing.success) {
            result = new PageReference('/' + thing.Id);
        } else {
            ApexPages.addMessage(new ApexPages.Message(
                'Error: ' + thin.ErrorMessage,
                ApexPages.Severity.FATAL
            ));
        }

        return result; // Returns null if there is an error
    }
}