Javascript 在高阶函数中包装superagent以记录全局错误?

Javascript 在高阶函数中包装superagent以记录全局错误?,javascript,ajax,error-handling,webpack,superagent,Javascript,Ajax,Error Handling,Webpack,Superagent,因此,我想使用winston记录我的应用程序发出的所有请求。我通过superagent发出所有API请求,我基本上想建立某种中间件,如: // Global error middleware superagent.on('request', req => winston.log(req)) 然后在另一个文件中,正常导入superagent,并使其正常工作: import superagent from 'superagent' const request = superagent.get

因此,我想使用
winston
记录我的应用程序发出的所有请求。我通过
superagent
发出所有API请求,我基本上想建立某种中间件,如:

// Global error middleware
superagent.on('request', req => winston.log(req))
然后在另一个文件中,正常导入
superagent
,并使其正常工作:

import superagent from 'superagent'
const request = superagent.get('url' ..etc)
我不想导入我自己的包装函数,因为我担心团队中的其他开发人员会忘记这种做法,直接从superagent导入,从而避免错误日志记录。显然,我也不想在
superagent
样板文件的几十个实例中编写日志记录


我在谷歌搜索了一下,惊奇地发现,基本上没有解决方案。有办法吗?或者,我想我可以在我的网页配置中设置一个别名?

您可以在项目中创建一个子包并链接到该子包。您需要实现几个文件:

首先为该子包创建一个文件夹,在我的例子中:
lib/superagent+logger
(相对于主项目文件夹)

可以根据需要更改名称,但以下文件中的
名称除外

lib/superagent+logger/package.json

{
    "name": "superagent",
    "version": "0.1.0",
    "description": "superagent wrapper that adds a global logger",
    "main": "index.js",
    "dependencies": {
        "superagent": "latest"
    }
}
{
    ...
    "dependencies": {
        "superagent": "file:lib/superagent+logger"
    }
}
名称对模拟超级代理很重要,不能更改

lib/superagent+logger/index.js

var superagent = require("superagent");

function logRequest(req){
    //that's the part you'd want to implement
    console.log('tracing signal to ', JSON.stringify(req.url));
}

function Smith(){ return superagent.apply(null, arguments).on('request', logRequest); }
Object.setPrototypeOf(Smith, superagent);
module.exports = Object.assign( 
    Smith, 
    {
        Request(method, url){
            return superagent.Request(method, url).on('request', logRequest)
        },
        agent(options){
            return superagent.agent(options).on('request', logRequest)
        },
        Response(req){
            return superagent.Response(req).on('request', logRequest)
        },
        acl(url, data, fn){
            return superagent.acl(url, data, fn).on('request', logRequest)
        },
        bind(url, data, fn){
            return superagent.bind(url, data, fn).on('request', logRequest)
        },
        checkout(url, data, fn){
            return superagent.checkout(url, data, fn).on('request', logRequest)
        },
        connect(url, data, fn){
            return superagent.connect(url, data, fn).on('request', logRequest)
        },
        copy(url, data, fn){
            return superagent.copy(url, data, fn).on('request', logRequest)
        },
        delete(url, data, fn){
            return superagent.delete(url, data, fn).on('request', logRequest)
        },
        get(url, data, fn){
            return superagent.get(url, data, fn).on('request', logRequest)
        },
        head(url, data, fn){
            return superagent.head(url, data, fn).on('request', logRequest)
        },
        link(url, data, fn){
            return superagent.link(url, data, fn).on('request', logRequest)
        },
        lock(url, data, fn){
            return superagent.lock(url, data, fn).on('request', logRequest)
        },
        "m-search": function(url, data, fn){
            return superagent["m-search"](url, data, fn).on('request', logRequest)
        },
        merge(url, data, fn){
            return superagent.merge(url, data, fn).on('request', logRequest)
        },
        mkactivity(url, data, fn){
            return superagent.mkactivity(url, data, fn).on('request', logRequest)
        },
        mkcalendar(url, data, fn){
            return superagent.mkcalendar(url, data, fn).on('request', logRequest)
        },
        mkcol(url, data, fn){
            return superagent.mkcol(url, data, fn).on('request', logRequest)
        },
        move(url, data, fn){
            return superagent.move(url, data, fn).on('request', logRequest)
        },
        notify(url, data, fn){
            return superagent.notify(url, data, fn).on('request', logRequest)
        },
        options(url, data, fn){
            return superagent.options(url, data, fn).on('request', logRequest)
        },
        patch(url, data, fn){
            return superagent.patch(url, data, fn).on('request', logRequest)
        },
        post(url, data, fn){
            return superagent.post(url, data, fn).on('request', logRequest)
        },
        propfind(url, data, fn){
            return superagent.propfind(url, data, fn).on('request', logRequest)
        },
        proppatch(url, data, fn){
            return superagent.proppatch(url, data, fn).on('request', logRequest)
        },
        purge(url, data, fn){
            return superagent.purge(url, data, fn).on('request', logRequest)
        },
        put(url, data, fn){
            return superagent.put(url, data, fn).on('request', logRequest)
        },
        rebind(url, data, fn){
            return superagent.rebind(url, data, fn).on('request', logRequest)
        },
        report(url, data, fn){
            return superagent.report(url, data, fn).on('request', logRequest)
        },
        search(url, data, fn){
            return superagent.search(url, data, fn).on('request', logRequest)
        },
        subscribe(url, data, fn){
            return superagent.subscribe(url, data, fn).on('request', logRequest)
        },
        trace(url, data, fn){
            return superagent.trace(url, data, fn).on('request', logRequest)
        },
        unbind(url, data, fn){
            return superagent.unbind(url, data, fn).on('request', logRequest)
        },
        unlink(url, data, fn){
            return superagent.unlink(url, data, fn).on('request', logRequest)
        },
        unlock(url, data, fn){
            return superagent.unlock(url, data, fn).on('request', logRequest)
        },
        unsubscribe(url, data, fn){
            return superagent.unsubscribe(url, data, fn).on('request', logRequest)
        },
        del(url, data, fn){
            return superagent.del(url, data, fn).on('request', logRequest)
        }
    }
);

//wrapper built and ready to use
console.log("Hello Mr Anderson\n");
在您的实际项目中:

/package.json

{
    "name": "superagent",
    "version": "0.1.0",
    "description": "superagent wrapper that adds a global logger",
    "main": "index.js",
    "dependencies": {
        "superagent": "latest"
    }
}
{
    ...
    "dependencies": {
        "superagent": "file:lib/superagent+logger"
    }
}
还有一个简单的测试:

var request = require("superagent");
void request.get("http://google.de").end();
编辑:

我在
lib/superagent+logger/index.js
中写出了之前动态构建的部分,这让您感到困惑

+没有动态生成的方法
-没有动态生成的方法

该模块没有什么令人惊讶的地方,但它也不适应内部
superagent
实现/版本的变化;您必须手动执行此操作


当我读到这篇文章时,可能有一些方法你想删除。我的主要目标是如何将这个包装器注入/加载到实际的项目中,而不是超级代理本身。

你的
index.js
非常难读,充满了奇怪的语法选择和正则表达式。想解释一下它到底在做什么吗?替换
superagent
方法?@johndoe。不,它根本不会修改superagent。它把它包起来了。首先,它为superagent方法创建一个名为“Smith”的包装器,并为superagent上的每个方法创建一个包装器,该包装器将调用转发给相应的superagent方法,并在('request',logRequest)
上追加一个
。“怪异”部分创建一个动态函数体作为字符串来命名包装器方法,并为它们提供相同的参数。。。基本上只是错误报告的糖(我猜3AM支付了费用)。您可以记录
方法
以检出构建的函数体。我马上添加了一个更简单的版本。根本无法让它工作。为什么要使用本地文件,然后通过npm进行安装?为什么不干脆给它取个别名?@JohnDoe,因为我对别名了解不够,无法满足你的要求。与实际的superagent包类似,对主应用程序(并通过
require('superagent')
解析)起作用的“某物”,但运行一些附加代码。对我来说,这听起来像是一个模块,我试图解决的是两个模块之间的冲突,两个模块在同一个应用程序中使用相同的名称(superagent)。无论如何,我使用的是ES6,所以模块解析是不同的。不过谢谢你的努力,如果没有其他人回复,我会接受它作为解决方案。