Skip to content

Commit 0ce0d57

Browse files
authored
Merge pull request #193 from SiaFoundation/christopher/404-no-block
HTTP error 404 if block doesn't exist instead of 500
2 parents 4374873 + e5fd778 commit 0ce0d57

File tree

5 files changed

+43
-14
lines changed

5 files changed

+43
-14
lines changed

api/server.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,10 @@ func (s *server) blocksIDHandler(jc jape.Context) {
278278
return
279279
}
280280
block, err := s.e.Block(id)
281-
if jc.Check("failed to get block", err) != nil {
281+
if errors.Is(err, explorer.ErrNoBlock) {
282+
jc.Error(err, http.StatusNotFound)
283+
return
284+
} else if jc.Check("failed to get block", err) != nil {
282285
return
283286
}
284287
jc.Encode(block)

explorer/explorer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ var (
2020
// database or there is no tips at all.
2121
ErrNoTip = errors.New("no tip found")
2222

23+
// ErrNoBlock is returned when we are unable to find the block in the
24+
// database.
25+
ErrNoBlock = errors.New("block not found")
26+
2327
// ErrContractNotFound is returned when ContractRevisions is unable to find
2428
// the specified contract ID.
2529
ErrContractNotFound = errors.New("contract not found")

persist/sqlite/blocks.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ func (s *Store) Block(id types.BlockID) (result explorer.Block, err error) {
1515
var v2Height uint64
1616
var v2Commitment types.Hash256
1717
err := tx.QueryRow(`SELECT parent_id, nonce, timestamp, height, leaf_index, v2_height, v2_commitment FROM blocks WHERE id = ?`, encode(id)).Scan(decode(&result.ParentID), decode(&result.Nonce), decode(&result.Timestamp), &result.Height, decode(&result.LeafIndex), decodeNull(&v2Height), decodeNull(&v2Commitment))
18-
if err != nil {
18+
if errors.Is(err, sql.ErrNoRows) {
19+
return explorer.ErrNoBlock
20+
} else if err != nil {
1921
return fmt.Errorf("failed to get block: %w", err)
2022
}
2123
result.MinerPayouts, err = blockMinerPayouts(tx, id)
@@ -56,6 +58,22 @@ func (s *Store) Block(id types.BlockID) (result explorer.Block, err error) {
5658
return
5759
}
5860

61+
// Tip implements explorer.Store.
62+
func (s *Store) Tip() (result types.ChainIndex, err error) {
63+
const query = `SELECT id, height FROM blocks ORDER BY height DESC LIMIT 1`
64+
err = s.transaction(func(dbTxn *txn) error {
65+
err := dbTxn.QueryRow(query).Scan(decode(&result.ID), &result.Height)
66+
if errors.Is(err, sql.ErrNoRows) {
67+
return explorer.ErrNoTip
68+
} else if err != nil {
69+
return err
70+
}
71+
72+
return nil
73+
})
74+
return
75+
}
76+
5977
// BestTip implements explorer.Store.
6078
func (s *Store) BestTip(height uint64) (result types.ChainIndex, err error) {
6179
err = s.transaction(func(tx *txn) error {

persist/sqlite/consensus.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,15 +1192,3 @@ func (s *Store) UpdateChainState(reverted []chain.RevertUpdate, applied []chain.
11921192
return nil
11931193
})
11941194
}
1195-
1196-
// Tip implements explorer.Store.
1197-
func (s *Store) Tip() (result types.ChainIndex, err error) {
1198-
const query = `SELECT id, height FROM blocks ORDER BY height DESC LIMIT 1`
1199-
err = s.transaction(func(dbTxn *txn) error {
1200-
return dbTxn.QueryRow(query).Scan(decode(&result.ID), &result.Height)
1201-
})
1202-
if errors.Is(err, sql.ErrNoRows) {
1203-
return types.ChainIndex{}, explorer.ErrNoTip
1204-
}
1205-
return
1206-
}

persist/sqlite/consensus_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,22 @@ func TestTip(t *testing.T) {
506506
}
507507
}
508508

509+
func TestMissingBlock(t *testing.T) {
510+
_, _, cm, db := newStore(t, false, nil)
511+
512+
id := cm.Tip().ID
513+
_, err := db.Block(id)
514+
if err != nil {
515+
t.Fatalf("error retrieving genesis block: %v", err)
516+
}
517+
518+
id[0] ^= 255
519+
_, err = db.Block(id)
520+
if !errors.Is(err, explorer.ErrNoBlock) {
521+
t.Fatalf("did not get ErrNoBlock retrieving missing block: %v", err)
522+
}
523+
}
524+
509525
func TestFileContract(t *testing.T) {
510526
pk1 := types.GeneratePrivateKey()
511527
addr1 := types.StandardUnlockHash(pk1.PublicKey())

0 commit comments

Comments
 (0)