There are 3 kinds of messages you can provide to users in a Python Toolbox: messages.addMessage(), messages.addWarningMessage(), and messages.addErrorMessage(). addMessage() and addWarningMessage() are both considered a "success", the only difference is that in Desktop GP results the warning message will be green. You can see an example of a warning message when you run DeleteFeatures. It will successfully delete the features but warns you that you now have an empty dataset. addErrorMessage() is different. It indicates that the tool failed and in Desktop the message is in red.
When you publish a GP service, there is a setting in Parameters to denote the "Message Level" for the service. You can set it to None, Info, Warning, Error. Fairly self-explanatory there. Regardless of the message level, the REST json response will always include a jobStatus that will be either esriJobSucceeded or esriJobFailed. If the job succeeded, you will get messages back that match the Message Level of the service. None: no messages; Info: all messages; Warning: only .addWarningMessage() messages. If the job failed, either because you used .addErrorMessage() or there was some unhandled error, you will always get at least some messages. If your message level is None, you will get only the fact that the tool failed. If you used at least message level Error, you will get back any custom .addErrorMessage() messages.
In the Web AppBuilder geoprocessing widget, while the job is running you will see some messaging in the tool's Output tab. If the job succeeded, the Output tab will be blank - no messages remain even if you provided lots of feedback about the tool's execution using .addMessage() and regardless of the message level of the service. If the job failed then messages from the REST response will remain in the Output window (I wish it did that for successful jobs too!), and you will always see at least the fact that the tool failed, even if the message level is None. One note, if the service's message level is Info you will get much more verbose messaging than if it is Warning or Error. If your service's primary consumer is WAB, I recommend using Error. If other REST clients will use the job results and you want to display success messages use Info.
I made a demo WAB app to show the effect of a gp service's message level on the WAB gp widget. The gp tool takes a parameter indicating what kind of message to return. I published it with each of the 4 types of message levels to separate services.
service urls (asynchronous execution):