mirror of
https://github.com/Permissionless-Software-Foundation/psf-bch-api-base.git
synced 2026-09-21 16:52:00 -07:00
Merge pull request #24 from Permissionless-Software-Foundation/ct-unstable
Reducing logging noise for common errors
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Summary
|
## 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
|
## 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:
|
- Added structured Winston metadata fields to request logs:
|
||||||
- `client_ip` from `req.ip`
|
- `client_ip` from `req.ip`
|
||||||
- `remote_address` from `req.socket.remoteAddress`
|
- `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
|
## 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.
|
- 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.
|
- `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.
|
- 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.
|
||||||
|
|||||||
@@ -65,17 +65,28 @@ class FulcrumAPIAdapter {
|
|||||||
// Attempt to extract error message from response data
|
// Attempt to extract error message from response data
|
||||||
if (err.response && err.response.data) {
|
if (err.response && err.response.data) {
|
||||||
const data = 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
|
// Handle structured error responses
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
return this._formatError(data.error, err.response.status || 400)
|
return this._formatError(data.error, status)
|
||||||
}
|
}
|
||||||
// Handle string error messages
|
// Handle string error messages
|
||||||
if (typeof data === 'string') {
|
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
|
// Handle object responses that might contain error info
|
||||||
if (typeof data === 'object' && data.message) {
|
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
|
// Fallback to returning the status
|
||||||
return this._formatError('Fulcrum API error', err.response.status || 500)
|
return this._formatError('Fulcrum API error', err.response.status || 500)
|
||||||
@@ -119,6 +130,25 @@ class FulcrumAPIAdapter {
|
|||||||
status: status || 500
|
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
|
export default FulcrumAPIAdapter
|
||||||
|
|||||||
@@ -87,6 +87,16 @@ class FulcrumRESTController {
|
|||||||
return cashAddr
|
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
|
* @api {get} /v6/fulcrum/balance/:address Get balance for a single address
|
||||||
* @apiName GetBalance
|
* @apiName GetBalance
|
||||||
@@ -239,10 +249,10 @@ class FulcrumRESTController {
|
|||||||
try {
|
try {
|
||||||
const txid = req.params.txid
|
const txid = req.params.txid
|
||||||
|
|
||||||
if (typeof txid !== 'string') {
|
if (!this._isValidTxid(txid)) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
success: false,
|
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) {
|
handleError (err, res) {
|
||||||
wlogger.error('Error in FulcrumRESTController:', err)
|
|
||||||
|
|
||||||
const status = err.status || 500
|
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'
|
const message = err.message || 'Internal server error'
|
||||||
|
|
||||||
return res.status(status).json({ error: message })
|
return res.status(status).json({ error: message })
|
||||||
|
|||||||
@@ -62,14 +62,9 @@ class FulcrumUseCases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getTransactionDetails ({ txid }) {
|
async getTransactionDetails ({ txid }) {
|
||||||
try {
|
const response = await this.fulcrum.get(`electrumx/tx/data/${txid}`)
|
||||||
const response = await this.fulcrum.get(`electrumx/tx/data/${txid}`)
|
// console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
|
||||||
// console.log(`getTransactionDetails() TXID ${txid}: ${JSON.stringify(response, null, 2)}`)
|
return response
|
||||||
return response
|
|
||||||
} catch (err) {
|
|
||||||
wlogger.error('Error in FulcrumUseCases.getTransactionDetails()', err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTransactionDetailsBulk ({ txids, verbose }) {
|
async getTransactionDetailsBulk ({ txids, verbose }) {
|
||||||
|
|||||||
Reference in New Issue
Block a user