Reducing logging noise for common errors

This commit is contained in:
Chris Troutner
2026-03-17 16:19:36 -07:00
parent 03caa3cd67
commit cff0e89b0d
4 changed files with 75 additions and 16 deletions
+17 -1
View File
@@ -2,7 +2,7 @@
## Summary
Enhanced REST request logging to capture client network identity in Winston logs and enabled proxy-aware IP resolution.
Enhanced REST request logging to capture client network identity in Winston logs, enabled proxy-aware IP resolution, and reduced Fulcrum error-log noise for expected missing-transaction requests.
## Changes Made
@@ -12,6 +12,19 @@ Enhanced REST request logging to capture client network identity in Winston logs
- Added structured Winston metadata fields to request logs:
- `client_ip` from `req.ip`
- `remote_address` from `req.socket.remoteAddress`
- Updated `src/adapters/fulcrum-api.js`:
- Added parsing helpers to normalize Fulcrum error messages from multiple response shapes.
- Mapped common daemon missing-TX error (`No such mempool or blockchain transaction`) to:
- status `404`
- message `Transaction not found`
- Updated `src/use-cases/fulcrum-use-cases.js`:
- Removed duplicate error logging in `getTransactionDetails()` and now rethrows adapter errors without a second error-level log.
- Updated `src/controllers/rest-api/fulcrum/controller.js`:
- Added TXID validation (`64`-character hex) for `GET /v6/fulcrum/tx/data/:txid`.
- Updated `handleError()` logging policy:
- `Transaction not found` (`404`) logs at `info`
- other `4xx` logs at `warn`
- `5xx` logs at `error`
## Useful Fields Available for REST Request Logging
@@ -58,3 +71,6 @@ Enhanced REST request logging to capture client network identity in Winston logs
- Request logs now preserve existing behavior while adding IP attribution fields.
- `trust proxy` ensures `req.ip` is proxy-aware when the server is deployed behind a reverse proxy.
- The project now has a documented list of high-value request fields for future logging expansion.
- Fulcrum missing-transaction lookups now return cleaner API semantics (`404 Transaction not found`).
- Duplicate error logs for a single missing TX lookup were removed.
- Invalid TXIDs are rejected early with a `400` validation error.
+33 -3
View File
@@ -65,17 +65,28 @@ class FulcrumAPIAdapter {
// Attempt to extract error message from response data
if (err.response && err.response.data) {
const data = err.response.data
const status = err.response.status || 400
const message = this._extractErrorMessage(data)
if (this._isCommonMissingTxError(message)) {
return this._formatError('Transaction not found', 404)
}
if (message) {
return this._formatError(message, status)
}
// Handle structured error responses
if (data.error) {
return this._formatError(data.error, err.response.status || 400)
return this._formatError(data.error, status)
}
// Handle string error messages
if (typeof data === 'string') {
return this._formatError(data, err.response.status || 400)
return this._formatError(data, status)
}
// Handle object responses that might contain error info
if (typeof data === 'object' && data.message) {
return this._formatError(data.message, err.response.status || 400)
return this._formatError(data.message, status)
}
// Fallback to returning the status
return this._formatError('Fulcrum API error', err.response.status || 500)
@@ -119,6 +130,25 @@ class FulcrumAPIAdapter {
status: status || 500
}
}
_extractErrorMessage (data) {
if (!data) return ''
if (typeof data === 'string') return data
if (typeof data === 'object') {
if (typeof data.error === 'string') return data.error
if (data.error && typeof data.error === 'object' && data.error.message) return data.error.message
if (data.message) return data.message
}
return ''
}
_isCommonMissingTxError (message = '') {
return typeof message === 'string' &&
message.includes('No such mempool or blockchain transaction')
}
}
export default FulcrumAPIAdapter
+22 -4
View File
@@ -87,6 +87,16 @@ class FulcrumRESTController {
return cashAddr
}
_isValidTxid (txid) {
return typeof txid === 'string' && /^[a-fA-F0-9]{64}$/.test(txid)
}
_isCommonMissingTxError (err) {
return err?.status === 404 &&
typeof err?.message === 'string' &&
err.message.includes('Transaction not found')
}
/**
* @api {get} /v6/fulcrum/balance/:address Get balance for a single address
* @apiName GetBalance
@@ -239,10 +249,10 @@ class FulcrumRESTController {
try {
const txid = req.params.txid
if (typeof txid !== 'string') {
if (!this._isValidTxid(txid)) {
return res.status(400).json({
success: false,
error: 'txid must be a string'
error: 'txid must be a 64-character hex string'
})
}
@@ -575,9 +585,17 @@ class FulcrumRESTController {
}
handleError (err, res) {
wlogger.error('Error in FulcrumRESTController:', err)
const status = err.status || 500
const isCommonMissingTxError = this._isCommonMissingTxError(err)
if (isCommonMissingTxError) {
wlogger.info(`Fulcrum transaction not found: ${err.message}`)
} else if (status >= 500) {
wlogger.error('Error in FulcrumRESTController:', err)
} else {
wlogger.warn(`Fulcrum client error (${status}): ${err.message}`)
}
const message = err.message || 'Internal server error'
return res.status(status).json({ error: message })
+3 -8
View File
@@ -62,14 +62,9 @@ class FulcrumUseCases {
}
async getTransactionDetails ({ txid }) {
try {
const response = await this.fulcrum.get(`electrumx/tx/data/${txid}`)
// console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
return response
} catch (err) {
wlogger.error('Error in FulcrumUseCases.getTransactionDetails()', err)
throw err
}
const response = await this.fulcrum.get(`electrumx/tx/data/${txid}`)
// console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
return response
}
async getTransactionDetailsBulk ({ txids, verbose }) {