@@ -11,6 +11,14 @@ import {
11
11
setETagCacheHeaders ,
12
12
} from '../../../api/controllers/cache-controller' ;
13
13
14
+ class NameRedirectError extends Error {
15
+ constructor ( message : string ) {
16
+ super ( message ) ;
17
+ this . message = message ;
18
+ this . name = this . constructor . name ;
19
+ }
20
+ }
21
+
14
22
export function createBnsNamesRouter ( db : PgStore , chainId : ChainID ) : express . Router {
15
23
const router = express . Router ( ) ;
16
24
const cacheHandler = getETagCacheHandler ( db ) ;
@@ -85,64 +93,77 @@ export function createBnsNamesRouter(db: PgStore, chainId: ChainID): express.Rou
85
93
asyncHandler ( async ( req , res , next ) => {
86
94
const { name } = req . params ;
87
95
const includeUnanchored = isUnanchoredRequest ( req , res , next ) ;
88
- let nameInfoResponse : BnsGetNameInfoResponse ;
89
- // Subdomain case
90
- if ( name . split ( '.' ) . length == 3 ) {
91
- const subdomainQuery = await db . getSubdomain ( { subdomain : name , includeUnanchored } ) ;
92
- if ( ! subdomainQuery . found ) {
93
- const namePart = name . split ( '.' ) . slice ( 1 ) . join ( '.' ) ;
94
- const resolverResult = await db . getSubdomainResolver ( { name : namePart } ) ;
95
- if ( resolverResult . found ) {
96
- if ( resolverResult . result === '' ) {
97
- res . status ( 404 ) . json ( { error : `missing resolver from a malformed zonefile` } ) ;
98
- return ;
96
+
97
+ await db
98
+ . sqlTransaction ( async sql => {
99
+ let nameInfoResponse : BnsGetNameInfoResponse ;
100
+ // Subdomain case
101
+ if ( name . split ( '.' ) . length == 3 ) {
102
+ const subdomainQuery = await db . getSubdomain ( {
103
+ subdomain : name ,
104
+ includeUnanchored,
105
+ } ) ;
106
+ if ( ! subdomainQuery . found ) {
107
+ const namePart = name . split ( '.' ) . slice ( 1 ) . join ( '.' ) ;
108
+ const resolverResult = await db . getSubdomainResolver ( { name : namePart } ) ;
109
+ if ( resolverResult . found ) {
110
+ if ( resolverResult . result === '' ) {
111
+ throw { error : `missing resolver from a malformed zonefile` } ;
112
+ }
113
+ throw new NameRedirectError ( `${ resolverResult . result } /v1/names${ req . url } ` ) ;
114
+ }
115
+ throw { error : `cannot find subdomain ${ name } ` } ;
116
+ }
117
+ const { result } = subdomainQuery ;
118
+
119
+ nameInfoResponse = {
120
+ address : result . owner ,
121
+ blockchain : bnsBlockchain ,
122
+ last_txid : result . tx_id ,
123
+ resolver : result . resolver ,
124
+ status : 'registered_subdomain' ,
125
+ zonefile : result . zonefile ,
126
+ zonefile_hash : result . zonefile_hash ,
127
+ } ;
128
+ } else {
129
+ const nameQuery = await db . getName ( {
130
+ name,
131
+ includeUnanchored : includeUnanchored ,
132
+ chainId : chainId ,
133
+ } ) ;
134
+ if ( ! nameQuery . found ) {
135
+ throw { error : `cannot find name ${ name } ` } ;
99
136
}
100
- res . redirect ( `${ resolverResult . result } /v1/names${ req . url } ` ) ;
101
- return ;
137
+ const { result } = nameQuery ;
138
+ nameInfoResponse = {
139
+ address : result . address ,
140
+ blockchain : bnsBlockchain ,
141
+ expire_block : result . expire_block ,
142
+ grace_period : result . grace_period ,
143
+ last_txid : result . tx_id ? result . tx_id : '' ,
144
+ resolver : result . resolver ,
145
+ status : result . status ? result . status : '' ,
146
+ zonefile : result . zonefile ,
147
+ zonefile_hash : result . zonefile_hash ,
148
+ } ;
102
149
}
103
- res . status ( 404 ) . json ( { error : `cannot find subdomain ${ name } ` } ) ;
104
- return ;
105
- }
106
- const { result } = subdomainQuery ;
107
150
108
- nameInfoResponse = {
109
- address : result . owner ,
110
- blockchain : bnsBlockchain ,
111
- last_txid : result . tx_id ,
112
- resolver : result . resolver ,
113
- status : 'registered_subdomain' ,
114
- zonefile : result . zonefile ,
115
- zonefile_hash : result . zonefile_hash ,
116
- } ;
117
- } else {
118
- const nameQuery = await db . getName ( {
119
- name,
120
- includeUnanchored : includeUnanchored ,
121
- chainId : chainId ,
151
+ const response = Object . fromEntries (
152
+ Object . entries ( nameInfoResponse ) . filter ( ( [ _ , v ] ) => v != null )
153
+ ) ;
154
+ return response ;
155
+ } )
156
+ . then ( response => {
157
+ setETagCacheHeaders ( res ) ;
158
+ res . json ( response ) ;
159
+ } )
160
+ . catch ( error => {
161
+ if ( error instanceof NameRedirectError ) {
162
+ res . redirect ( error . message ) ;
163
+ } else {
164
+ res . status ( 400 ) . json ( error ) ;
165
+ }
122
166
} ) ;
123
- if ( ! nameQuery . found ) {
124
- res . status ( 404 ) . json ( { error : `cannot find name ${ name } ` } ) ;
125
- return ;
126
- }
127
- const { result } = nameQuery ;
128
- nameInfoResponse = {
129
- address : result . address ,
130
- blockchain : bnsBlockchain ,
131
- expire_block : result . expire_block ,
132
- grace_period : result . grace_period ,
133
- last_txid : result . tx_id ? result . tx_id : '' ,
134
- resolver : result . resolver ,
135
- status : result . status ? result . status : '' ,
136
- zonefile : result . zonefile ,
137
- zonefile_hash : result . zonefile_hash ,
138
- } ;
139
- }
140
-
141
- const response = Object . fromEntries (
142
- Object . entries ( nameInfoResponse ) . filter ( ( [ _ , v ] ) => v != null )
143
- ) ;
144
- setETagCacheHeaders ( res ) ;
145
- res . json ( response ) ;
146
167
} )
147
168
) ;
148
169
0 commit comments