I am not sure why you added iter, but it does stop at IndexError without it
>>> class NumbersDataset:
...     def __init__(self):
...         self.samples = [1,2,3,4,5,6,7,9,10]
...     def __len__(self):
...         return 3
...     def __getitem__(self, idx):
...         print("Trying", idx)
...         if idx>3:
...                 print("Raising Index error")
...                 raise IndexError
...         return self.samples[idx]
...
>>> dataset = NumbersDataset()
>>>
>>> len(dataset), len(list(dataset))
Trying 0
Trying 1
Trying 2
Trying 3
Trying 4
Raising Index error
(3, 4)

I think iter bypasses the getitem