Node.js服务器崩溃而没有错误消息

时间:2013-11-09 19:55:15

标签: node.js

我有一个Node.js服务器不断崩溃而不记录任何类型的错误消息。这是典型的情况吗?如何捕获错误并在崩溃之前将其记录下来?

5 个答案:

答案 0 :(得分:39)

一个好的开始是在为服务器设置监听器之前设置,尤其是在生产环境中,这是一个记录详细信息的异常处理程序。看看here

process.on('uncaughtException', function (exception) {
  console.log(exception); // to see your exception details in the console
  // if you are on production, maybe you can send the exception details to your
  // email as well ?
});

如果您使用的是Express.js,请查看here以了解如何查看错误的完整堆栈(如果您正在制作,最终会将其发送到您的电子邮件中)。 在这种情况下,告诉它在实例化侦听器之前为您提供完整的详细信息:

var express = require('express');
// ...
var app = express();
// ...
app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
// then, set the listener and do your stuff...

答案 1 :(得分:7)

要完成@matteofigus答案,您还可以listen for unhandled promise rejections

process.on('unhandledRejection', (reason, p) => {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

somePromise.then((res) => {
  return reportToUser(JSON.pasre(res)); // note the typo (`pasre`)
}); // no `.catch` or `.then`

答案 2 :(得分:1)

Node v6.11.0,Windows 10.

尝试其他建议无效 - 应用程序停止,即使使用

也没有错误
process.on('uncaughtException',...)
process.on('unhandledRejection',....)

最后跟踪退出/崩溃到递归函数调用。以下代码演示了该问题;

"use strict" ;

process.on('uncaughtException', function (exception) {
  console.log(exception); 
});

var count = 0 ;
function recursiveFunction(){
    console.log(count++);
    recursiveFunction();
}
recursiveFunction() ;

这将运行到目前为止然后停止。 Try / Catch也没有工作 - 尝试如上所述;

function recursiveFunction(){
    console.log(count++);
    try{
        recursiveFunction();
    }
    catch(e){
        console.log("recursion error");
    }
}

再没有 - 只是停下来。

解决方法(无需重新设计代码)是使用setImmediate(以避免递归过程);

function recursiveFunction(){
    console.log(count++);
    setImmediate(recursiveFunction);
}

(我最终ctrl-c'这是为了阻止它。)

报告node github issues

答案 3 :(得分:0)

您可以使用名为' errorhandler'的中间件&安培;与记录器' (log4js-npm-package)您可以保留所有错误异常的日志。这是Errorhandler的代码:

//中间件:Catch-All错误处理程序。因此,我们记录错误,但不要将内部错误详细信息泄露给客户端。

TextView tv_loading;
String dest_file_path = "test.pdf";
int downloadedSize = 0, totalsize;
String download_file_url = "http://ilabs.uw.edu/sites/default/files/sample_0.pdf";
float per = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    tv_loading = new TextView(this);
    setContentView(tv_loading);
    tv_loading.setGravity(Gravity.CENTER);
    tv_loading.setTypeface(null, Typeface.BOLD);
    downloadAndOpenPDF();
}

void downloadAndOpenPDF() {
    new Thread(new Runnable() {
        public void run() {
            Uri path = Uri.fromFile(downloadFile(download_file_url));
            try {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(path, "application/pdf");
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                finish();
            } catch (ActivityNotFoundException e) {
                tv_loading
                        .setError("PDF Reader application is not installed in your device");
            }
        }
    }).start();

}

File downloadFile(String dwnload_file_path) {
    File file = null;
    try {

        URL url = new URL(dwnload_file_path);
        HttpURLConnection urlConnection = (HttpURLConnection) url
                .openConnection();

        urlConnection.setRequestMethod("GET");
        urlConnection.setDoOutput(true);

        // connect
        urlConnection.connect();

        // set the path where we want to save the file
        File SDCardRoot = Environment.getExternalStorageDirectory();
        // create a new file, to save the downloaded file
        file = new File(SDCardRoot, dest_file_path);

        FileOutputStream fileOutput = new FileOutputStream(file);

        // Stream used for reading the data from the internet
        InputStream inputStream = urlConnection.getInputStream();

        // this is the total size of the file which we are
        // downloading
        totalsize = urlConnection.getContentLength();
        setText("Starting PDF download...");

        // create a buffer...
        byte[] buffer = new byte[1024 * 1024];  
        int bufferLength = 0;

        while ((bufferLength = inputStream.read(buffer)) > 0) {
            fileOutput.write(buffer, 0, bufferLength);
            downloadedSize += bufferLength;
            per = ((float) downloadedSize / totalsize) * 100;
            setText("Total PDF File size  : "
                    + (totalsize / 1024)
                    + " KB\n\nDownloading PDF " + (int) per
                    + "% complete");
        }
        // close the output stream when complete //
        fileOutput.close();
        setText("Download Complete. Open PDF Application installed in the device.");

    } catch (final MalformedURLException e) {
        setTextError("Some error occured. Press back and try again.",
                Color.RED);
    } catch (final IOException e) {
        setTextError("Some error occured. Press back and try again.",
                Color.RED);
    } catch (final Exception e) {
        setTextError(
                "Failed to download image. Please check your internet connection.",
                Color.RED);
    }
    return file;
}

void setTextError(final String message, final int color) {
    runOnUiThread(new Runnable() {
        public void run() {
            tv_loading.setTextColor(color);
            tv_loading.setText(message);
        }
    });

}

void setText(final String txt) {
    runOnUiThread(new Runnable() {
        public void run() {
            tv_loading.setText(txt);
        }
    });

}

答案 4 :(得分:0)

万一有人遇到与我类似的问题:我有一台崩溃的Node.js服务器,完全没有错误,并且花了一个小时才意识到我的原因是因为我在我的代码中写了一些东西像writeFileSync("./foo.json", "…")这样的文件,通常当然可以,但是这导致服务器“崩溃”,因为我使用PM2来“监视”服务器目录中的文件更改-即,只要服务器目录,PM2重新启动服务器。我通过为watch_ignore文件夹添加.data配置并将foo.json放在其中来解决了这个问题。