Right! The key thing to remember in this chunk of code is that the loops are over the output space, not the input space. As Tom describes, you compute the start and end position in the input space based on the loop variable (h or w in the output space) and then taking into account the stride and the filter size. The symptom you show means that you are running off the end of the input array in the w dimension. Note that the test case here is not typical of actual problems in that the nH_{prev} and nW_{prev} values are not symmetrical. The nW_{prev} is bigger. So perhaps you have to h and w reversed or something of that nature.
As one way to debug, try adding some print statements to show the various shapes that you get. For comparison, here’s what I get for the one test test for conv_block with some print statements as I am suggesting:
New dimensions = 3 by 4
Shape Z = (2, 3, 4, 8)
Shape A_prev_pad = (2, 7, 9, 4)
Z[0,0,0,0] = -2.651123629553914
Z[1,2,3,7] = 0.4427056509973153
Z's mean =
0.5511276474566768
Z[0,2,1] =
[-2.17796037 8.07171329 -0.5772704 3.36286738 4.48113645 -2.89198428
10.99288867 3.03171932]
cache_conv[0][1][2][3] =
[-1.1191154 1.9560789 -0.3264995 -1.34267579]