Objects have attributes and methods. Each method fulfills a part of the overall purpose of the object. Some type of methods, like constructors and getters and setters, are performing the life cycle management of the attributes and the object itself. Other methods return the state of the object and its attributes. Those methods are normally non void.
Void methods come in two flavors:
1. concerning the life cycle management of the object or the attributes.
2. having an output that is completely handled within the method and should not cause any state of change anywhere else.
ad 1. They belong to the internal working of the object.
ad 2. The information of the parameters is used to execute some work within the method. After the method has completed has there been no change in effect on the object itself nor on the internal status of one of the parameters.
But why should you make a method returning void and why not for instance a boolean (success or not)? The motivation for a method to return void (like in a setter) is that the method is intended to have no side effect. Returning true or false might be a side effect. Void implies that the method has no side effect when the method is executed as designed. A void method returning an exception is good, because an exception is not a side effect of the normal processing of a method.
A method returning void implies that it is by definition an isolated working method. A chain of void methods is a chain of loosely coupled methods, because no other method can rely on the outcome of its predecessor as no method has any outcome. There is a design pattern for this, namely the Chain of Responsibility design pattern. Chaining different loggers is a traditional example and the call to the subsequent filters within the servlet api.
To chain void methods in a meaningful way implies that the shared object on which those methods work is after each step in a state that is understandable by the void method working on the object. All subsequent calls may not rely on the outcome of its predecessor nor influence the working of the calls after its own call. The easiest way you can ensure that is by not letting them change the internal state of the object (like the logger example), or let each method change another part of the internal state of the object.
Void methods to be chained are in my opinion only those methods that have flavor 2 and share some type of processing. I would not chain the void methods concerning the life cycle of the class, because each method is a change of a different part of the whole state of the object. The presence of those methods can change over time with any change of design of the class, hence do I not advice to chain those methods. Furthermore are all exceptions thrown by the first type of void methods independent of each other, while you may expect that the exceptions thrown by the chained void methods of flavor 2 sharing some type of processing have something in common.