final version with error check