feature: Add onSuccess, onError hooks