util#debuglog TypeScript Examples
The following examples show how to use
util#debuglog.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ripple-api.ts From xrp-api with MIT License | 5 votes |
debug = debuglog('ripple-api')
Example #2
Source File: server.ts From xrp-api with MIT License | 5 votes |
private pathDebug: ReturnType<typeof debuglog>;
Example #3
Source File: server.ts From xrp-api with MIT License | 5 votes |
private serverDebug: ReturnType<typeof debuglog>;
Example #4
Source File: server.ts From xrp-api with MIT License | 4 votes |
public constructor(options: ServerOptions) {
const rippleApiService = options.rippleApiService;
this.serverDebug = (options.debuglog || debuglog)('server');
this.pathDebug = (options.debuglog || debuglog)('paths');
this.app = express();
// Use first: simple response logger
this.app.use((req: Request, res: Response, next: NextFunction) => {
res.on('finish', () => {
if (res.statusCode >= 100 && res.statusCode < 300) {
// Green for 1xx and 2xx
this.serverDebug('\x1b[32m%s\x1b[0m', req.method.toUpperCase() + ' ' + req.originalUrl + ' ' + res.statusCode);
} else {
// Red for the rest
this.serverDebug('\x1b[31m%s\x1b[0m', req.method.toUpperCase() + ' ' + req.originalUrl + ' ' + res.statusCode);
}
});
next();
});
// Connect to rippled before every API call
// this.app.use(rippleApiService.connectHandleFunction());
// TODO: replace with ripple-lib functionality
this.app.use(cors());
this.app.use(bodyParser.json());
/**
* Transform errors and validate all responses
*/
const validateAllResponses = (req: Request, res: ValidatableResponse, next: NextFunction): void => {
if (process.env.NODE_ENV != 'production') {
const send = res.send;
const resJson = res.json;
const log = this.pathDebug;
const expressOpenAPISendOrJson = (sendOrJson: Function, args: any): ValidatableResponse => { // eslint-disable-line @typescript-eslint/no-explicit-any
if (res.get('x-express-openapi-validation-error-for') !== undefined) {
return sendOrJson.apply(res, args);
}
const body = args[0];
if (typeof res.validateResponse !== 'function') {
// We know we cannot validate 404s
if (body.errors && body.errors[0].code !== 404) {
console.error('TypeError: res.validateResponse is not a function. Check `api-doc.yml`.');
}
return sendOrJson.apply(res, args);
}
const validation: ResponseValidation = res.validateResponse(res.statusCode, body) as ResponseValidation;
if (validation) {
// red
log('\x1b[31m%s\x1b[0m', `${res.req ? decodeURI(res.req.path) : ''} validation:`, validation);
// Set to avoid a loop, and to provide the original status code
res.set('x-express-openapi-validation-error-for', res.statusCode.toString());
} else {
// green
log('\x1b[32m%s\x1b[0m', `${res.req ? decodeURI(res.req.path) : ''} response validated`);
}
return sendOrJson.apply(res, args);
};
res.send = function expressOpenAPISend(...args) {
return expressOpenAPISendOrJson(send, args);
};
res.json = function expressOpenAPIJson(...args) {
interface MyError {
name: string;
message: string;
code: number;
}
function isErrorsResponse(json: FormattedSubmitResponse | Prepare | ErrorsResponse | object): json is ErrorsResponse {
return (json as ErrorsResponse).errors !== undefined;
}
const json = args[0];
if (json) {
const serializedErrors: MyError[] = [];
if (isErrorsResponse(json)) {
json.errors.forEach(err => {
if (err instanceof Error) {
const error: XrpApiError = err as XrpApiError;
// `RippledError`s contain `error` (e.g. `actNotFound` when source account is not found)
const name = (error.data?.error) || error.name;
// `RippledError`s contain `error_code` (e.g. `19` for `actNotFound`)
let code = error.code || (error.data && error.data.error_code) || ERRORS.CODES.UNSPECIFIED;
if (name === 'DisconnectedError') {
// name: DisconnectedError
// message: websocket was closed
code = ERRORS.CODES.WEBSOCKET;
if (!json.message) {
json.message = 'Lost connection to rippled. Please try again.';
}
}
if (name === 'actNotFound') {
const data = error.data;
if (!json.message && data?.account && data.ledger_current_index && data.request?.command) {
json.message = `The account (${data.account}) could not be found as of ledger ${data.ledger_current_index} (command: ${data.request.command})`;
}
}
if (!json.message) {
json.message = `${name}: ${error.message}`;
}
const e: XrpApiError = {
name,
message: error.message.replace(/"/g, "'"),
code
};
// Add `request` and `searched_all`, if present
if (error.data) {
if (error.data.request) {
e.request = error.data.request;
}
if (error.data.searched_all !== undefined) {
e.searched_all = error.data.searched_all;
}
if (error.hint !== undefined) {
e.hint = error.hint;
}
}
serializedErrors.push(e as MyError);
} else {
log('Warning: Got non-Error:', err);
serializedErrors.push(err);
}
});
json.errors = serializedErrors;
}
}
return expressOpenAPISendOrJson(resJson, args);
};
}
next();
};
this.app.use(validateAllResponses as RequestHandler);
initialize({
app: this.app,
apiDoc: './api-doc.yml',
dependencies: {
api: rippleApiService.api, // RippleAPI instance
log: this.pathDebug
},
paths: path.resolve(__dirname, '../dist/api-v3/paths/'),
pathsIgnore: new RegExp('\.(spec|test)$'),
promiseMode: true // Required to use promises in operations
});
interface ServerError {
status?: number;
message?: string;
errors?: ServerError[];
// ...
};
// Error handler for business logic
this.app.use((err: ServerError, req: Request, res: Response, next: NextFunction) => {
this.serverDebug('Server error:', err);
// Error: [TimeoutError()]
// (node:40986) [DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated
//
// GET /v3/accounts/rHn1DJH1dqzdZ5PrkFpgQPn6Tbn8wKsrk9/transactions 500
// [WebSocket Error] websocket: read EHOSTUNREACH
// Disconnected from rippled. Code: 1006
if (res.headersSent) {
this.serverDebug('headers were previously sent, not responding with error');
return next(err);
}
const status = err.status || 500;
delete err.status;
const message = err.message;
if (!err.errors) {
err = {errors: [err]};
}
if (message) {
// Include message first to improve readability.
err = Object.assign({message}, err);
}
res.status(status).json(err);
});
this.app.use((req, res, _next) => {
res.status(404);
if (req.path.startsWith('/v3') === false) {
res.json({
errors: [ERRORS.MISSING_V3]
});
} else {
res.json({
errors: [ERRORS.NOT_FOUND]
});
}
});
}