Как найти причину ошибки, когда пользователь отзывает белый экран открытой страницы? Как убедиться, что в определенном ежедневном выпуске нет ошибок? Насколько важно в это время отлавливать и сообщать об ошибках в выполнении кода.
Поскольку обнаружение ошибок и сообщение об ошибках — неотъемлемая часть ежедневной разработки, как вы их отлавливаете? мощныйtry...catch
try{
throw new Error()
} catch(e) {
// handle error
}
Кажется, как просто захват ошибок, но следующие сценарии не могут быть захвачены
try {
setTimeout(() => {
throw new Error('error')
})
} catch (e) {
// handle error
}
Вы обнаружите, что ошибка в приведенном выше примере не может быть перехвачена обычным образом.Кажется, что перехват ошибки не так прост, **try...catch** можно сделать, конечно, вы также можете обернуть слой **try ... поймать**, чтобы справиться.
В браузере **window.onerror** для обнаружения ваших ошибок
window.onerror = function (msg, url, row, col, error) {
console.log('error');
console.log({
msg, url, row, col, error
})
};
После обнаружения ошибки вы можете сообщить об ошибке.Метод сообщения очень прост.Вы можете создать простой **img** и указать адрес сообщения через **src**.Конечно, чтобы не отправлять слишком много запросы на отчетность, вы можете Отчет объединен, и отчет объединен. Данные могут периодически передаваться на сервер.
Но когда вы посмотрите на информацию, сообщаемую об ошибке, вы обнаружите некоторые такие ошибки **Ошибка скрипта**
Из-за политики браузера в отношении одного и того же источника **ошибка скрипта** выдается при ошибках с разными доменными именами. Как решить эту проблему? Тем более сейчас в основном ресурсы js будут размещаться на cdn.
решение
1: Все ресурсы размещаются под одним доменным именем. Но это также будет иметь проблему, заключающуюся в невозможности использования преимуществ cdn.
2. Добавьте поддержку междоменных ресурсов, добавьте поддержку междоменных запросов для основного домена в cdn и добавьте атрибут **crossorigin** в тег скрипта.
В использованииPromiseпроцесс, если у вас нетcatch, то вы можете поймать ошибку следующим образом
window.addEventListener("unhandledrejection", function(err, promise) {
// handle error here, for example log
});
Как ловить ошибки в NodeJs
Перехват ошибок в NodeJ важен, потому что неправильное обращение с ним может привести к лавине непригодных сервисов. Конечно не только умеете ловить ошибки, но и умеете избегать тех или иных ошибок.
-
Когда вы пишете функцию, вы, возможно, думали, что когда возникает ошибка при выполнении функции, я должен выбросить ее напрямую.throwили используйтеcallbackилиevent emitterИли это какой-то другой способ распространения ошибки?
-
Должен ли я проверить, является ли параметр правильным типом, не так ли?null
-
Что делать, если параметры не совпадают? выдать ошибку или пройтиcallbackКак насчет ошибок распределения другими способами?
-
Что, если будет сохранено достаточно ошибок, чтобы восстановить сцену ошибки?
-
Что делать, если вы хотите поймать некоторые ошибки исключения?try...catchещеdomain
Ошибка операции VS ошибка кодирования
1. Ошибка операции
Операции ошибки часто встречаются во время выполнения, а не из-за ошибок кода, но могут быть связаны с вашей системой, не хватающей памятью или не хватает ручек файлов, или нет сети и т. Д.
2. Ошибка кодирования
Легче понять, если кодировка неверна, это может бытьundefinedНо она вызывается как функция, либо возвращает неверный тип данных, либо утечки памяти и т.д.
Обработка операционных ошибок
-
Вы можете зарегистрировать ошибку, а затем ничего не делать
-
Вы также можете повторить попытку, например, потому что соединение с базой данных не удалось, но количество попыток должно быть ограничено.
-
Вы также можете указать интерфейс, а затем повторить попытку позже.
-
Возможно, вы также можете обработать это напрямую.Например, если путь не существует, создайте путь
Обработка ошибок кодирования
С плохой кодировкой нелегко справиться, потому что она вызвана ошибками кодирования. Хороший способ - перезапустить процесс, потому что
-
Вы не уверены, повлияет ли ошибка, вызванная ошибкой кодирования, на другие запросы.Например, ошибка установления соединения с базой данных не может быть успешной из-за ошибки кодирования, тогда другие ошибки сделают другие запросы недоступными.
-
Возможно, операция ввода-вывода выполняется до того, как будет выброшена ошибка, поэтому дескриптор ввода-вывода не может быть закрыт, что будет занимать память в течение длительного времени, что в итоге может привести к исчерпанию памяти и недоступности всей службы.
-
Два пункта, упомянутых выше, на самом деле не решают проблему вообще.Вы должны сделать тест перед выходом в сеть и контролировать его после выхода в сеть.При возникновении подобной ошибки вы должны следить за сигнализацией, обращать внимание и решать проблему.
Как распространять ошибки
-
В синхронной функции непосредственноthrowошибка
-
Для некоторых асинхронных функций ошибка может быть передана черезcallbackбросать
-
async/awaitможно использовать напрямуюtry..catchпоймать ошибки
-
EventEmitterбросатьerrorмероприятие
Эксплуатация и обслуживание NodeJ
Для приложения NodeJs трудно обеспечить стабильную работу только на уровне кода, но также и на уровне эксплуатации и обслуживания.
Мультипроцесс для управления вашим приложением
Как только однопроцессный nodejs зависает, вся служба становится недоступной, поэтому мне нужно несколько процессов, чтобы обеспечить доступность службы.Процесс отвечает только за запуск, завершение работы и перезапуск других процессов. Гарантируется, что процесс может быть перезапущен сразу же после его зависания.
может относиться кTSWДизайн многопроцессорный. Мастер отвечает за управление воркером.Рабочий и мастер поддерживают мониторинг сердцебиения.В случае потери они будут немедленно перезапущены.
domain
process.on('uncaughtException', function(err) {
console.error('Error caught in uncaughtException event:', err);
});
process.on('unhandleRejection', function(err) {
// TODO
})
При перехвате исключений в nodejs выше можно сказать, что это очень жестоко. Но когда исключение перехвачено в это время, вы потеряли контекст в это время, и можно сказать, что контекст здесь является запросом. Если в веб-службе происходит какая-то аномалия, все еще есть надежда, что некоторый восходящий контент может быть возвращен для улучшения взаимодействия с пользователем. Например, рендеринг на стороне сервера или изоморфизм, даже если он не работает, вы можете вернуть статический html и принять решение для понижения версии, но контекст в это время будет потерян. Выхода нет.
function domainMiddleware(options) {
return async function (ctx, next) {
const request = ctx.request;
const d = process.domain || domain.create();
d.request = request;
let errHandler = (err) => {
ctx.set('Content-Type', 'text/html; charset=UTF-8');
ctx.body = options.staticHtml;
};
d.on('error', errHandler);
d.add(ctx.request);
d.add(ctx.response);
try {
await next();
} catch(e) {
errHandler(e)
}
}
Выше приведено простое промежуточное программное обеспечение домена koa2, использующее мониторинг домена.errorСобытие, объекты запроса и ответа каждого запроса будут запускаться при возникновении ошибки.errorСобытия, когда возникает ошибка, могут ухудшаться в зависимости от контекста.
Как избежать утечек памяти
Утечки памяти очень распространены, особенно когда внешний интерфейс пишет внутренние программы, неправильное использование замыканий и циклических ссылок может привести к утечкам памяти.
-
Не блокируйте выполнение цикла событий, особенно больших циклов или операций синхронизации ввода-вывода.
for ( var i = 0; i < 10000000; i++ ) { var user = {}; user.name = 'outmem'; user.pass = '123456'; user.email = 'outmem[@outmem](/user/outmem).com'; }
Длинный цикл выше вызовет утечку памяти, потому что это синхронно выполняемый код, который будет выполняться в процессе.Когда цикл заканчивается, V8 не может восстановить память, сгенерированную циклом, что приведет к постоянному росту памяти. Другая возможная причина заключается в том, что это длительное выполнение блокирует вход узла в следующий цикл событий, что приводит к накоплению в очереди слишком большого количества обратных вызовов, ожидающих обработки, что еще больше увеличивает использование памяти. Как это решить?
годный к употреблениюsetTimeoutВыполнение операции в следующем цикле, сокращение длинных циклов и синхронизация сопротивления ввода-вывода процессу Блокировка выполнения следующего цикла также снизит производительность приложения.
-
Частные переменные и методы модуля всегда находятся в памяти.
var leakArray = [];
exports.leak = function () {
leakArray.push("leak" + Math.random());
};
Когда в узле требуется модуль, в конце формируется синглтон, то есть пока функция вызывается, память функции будет увеличиваться, а замыкание не будет переработано.leakМетод является приватным, и этот метод всегда будет существовать в памяти. Каждый запрос будет вызывать этот метод, после чего память на какое-то время взорвется.
Подобные сценарии довольно распространены
// main.js
function Main() {
this.greeting = 'hello world';
}
module.exports = Main;
var a = require('./main.js')();
var b = require('./main.js')();
a.greeting = 'hello a';
console.log(a.greeting); // hello a
console.log(b.greeting); // hello a
require является синглтоном, Когда каждый запрос выполняется на сервере, операция является синглтоном, так что переменные или атрибуты, сгенерированные каждым выполнением, всегда будут висеть на этом объекте, не могут быть переработаны и занимают много памяти.
На самом деле, вышеупомянутое может быть вызвано в соответствии со следующим методом вызова каждый раз, когда экземпляр создается и перерабатывается, когда он израсходован.
var a = new require('./main.js');
// TODO
Иногда трудно избежать некоторых проблем, которые могут вызвать утечку памяти, вы можете использоватьvmКаждый вызов выполняется в среде песочницы, и вызов возвращается, когда он израсходован.
- Последнее, что нужно сделать, это избегать циклических ссылок, которые также приведут к неперерабатываемым ресурсам.