Руководство по обработке исключений в Express PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Руководство по обработке исключений в Express

Введение

Исключения и ошибки неизбежны, когда пользователи взаимодействуют с любым приложением, и инженеры-программисты должны выбрать средства для обработки любой ошибки, которая может возникнуть — сознательно или неосознанно. В результате бэкэнд-разработчики, создающие API с помощью Express, вынуждены работать над тем, чтобы создать полезный, эффективный и удобный API. Что наиболее важно, так это обрабатывать ошибки таким образом, чтобы построить надежную систему, потому что это помогает сократить время разработки, прямые ошибки, проблемы с производительностью и определяет успех или масштабируемость разработки программного обеспечения.

Вам нужно зарегистрировать сообщение об ошибке, подавить ошибку, уведомить пользователей об ошибке или написать код для обработки ошибок? Не удивляйтесь больше.

В этом руководстве мы узнаем, как создать надежную кодовую базу обработки ошибок для приложений Express, которая поможет обнаруживать ошибки приложений и предпринимать оптимальные действия для восстановления любого приложения после корректного сбоя во время выполнения.

Примечание: Мы будем использовать Postman для тестирования API в нашей демонстрации. Вы можете скачать его на Страница загрузки почтальона. Кроме того, вы можете просто использовать браузер, командную строку curl инструмент или любой другой инструмент, с которым вы, возможно, знакомы.

Что такое обработка ошибок?

В разработке программного обеспечения есть два разных типа исключений: оперативный и программный.

  • Операционные сбои могут возникать во время выполнения, и чтобы предотвратить внезапное завершение работы приложения, мы должны изящно обрабатывать эти исключения с помощью эффективных методов обработки ошибок.
  • Программные исключения создаются вручную программистом при возникновении исключительного состояния.

Вы можете думать об операционных исключениях как о «неожиданных, но предвиденных» исключениях (таких как доступ к индексу за пределами границ), а о программных исключениях как о «ожидаемых и предвидимых» исключениях (таких как исключение форматирования чисел).

Обработка исключений — это процедура, используемая для поиска и исправления ошибок в программе. Обработка ошибок отправляет сообщения, содержащие тип произошедшей ошибки и стек, в котором произошла ошибка.

Примечание: В компьютерных науках исключения могут быть устранены и обычно связаны с операционными или программными проблемами во время выполнения. Ошибки обычно возникают из-за внешних факторов, таких как аппаратные ограничения, проблемы с подключением, нехватка памяти и т. д. В JavaScript эти термины часто используются взаимозаменяемо, а пользовательские исключения получаются из Error класс. В Error сам класс представляет как ошибки, так и исключения.

В Express обработка исключений относится к тому, как Express настраивается для перехвата и обработки синхронных и асинхронных исключений. Преимущество обработки исключений в Express заключается в том, что вам как разработчику не нужно писать собственные обработчики исключений; Express поставляется с обработчиком исключений по умолчанию. Обработчик исключений помогает выявлять ошибки и сообщать о них пользователю. Он также предоставляет различные стратегии исправления и реализует их для смягчения исключений.

Хотя может показаться, что под капотом скрывается множество вещей, обработка исключений в Express не замедляет общий процесс программы и не приостанавливает ее выполнение.

Понимание обработки исключений в Express

С обработчиком ошибок по умолчанию, который поставляется с Express, у нас есть набор функций промежуточного программного обеспечения, которые помогают автоматически обнаруживать ошибки в обработчиках маршрутов. Вскоре мы создадим проект, чтобы применить теорию на практике о том, как возвращать правильные ошибки в приложении Express и как не допустить утечки конфиденциальной информации.

Определение функции промежуточного программного обеспечения в Express

Функции промежуточного программного обеспечения для обработки ошибок определены таким образом, что они принимают Error object в качестве первого входного параметра, за которым следуют параметры по умолчанию любой другой функции промежуточного программного обеспечения: request, responseкачества next, next() функция пропускает все текущее промежуточное ПО к следующему обработчику ошибок для маршрутизатора.

Настройка обработки ошибок в Express

Выполните следующую команду в своем терминале, чтобы создать приложение Node и Express:

$ mkdir error-handling-express

Во вновь созданной папке инициализируем новый проект Node:

$ cd error-handling-express && npm init -y

Это создает package.json файл в нашей папке.

Чтобы создать сервер Express в нашем приложении Node, нам нужно установить express пакет, dotenv для автоматической загрузки переменных окружения в .env файл в process.env объект и nodemon для перезапуска приложения узла, если в каталоге отмечено изменение файла.

$ npm install express dotenv nodemon

Затем создайте app.js файл в папке проекта, который будет служить индексным файлом для приложения.

Теперь, когда мы установили все необходимые зависимости для нашего приложения Express, нам нужно настроить скрипт для чтения приложения в package.json файл. Чтобы добиться этого, package.json файл, так что scripts объект, как показано ниже:

"scripts": {
    "start": "nodemon app.js"
},

Кроме того, вы можете пропустить использование nodemonи использовать node app.js .

Настройка экспресс-сервера

Чтобы настроить сервер, мы должны сначала импортировать различные пакеты в app.js. Мы также создадим .env файл в каталоге проекта — для хранения всех переменных окружения для приложения:



const express = require('express')
require('dotenv').config

PORT=4000 

Мы определили номер порта для приложения в .env, который загружается и читается dotenv, и к ним можно будет получить доступ позже.

Инициализация экспресс-сервера

Теперь нам нужно инициализировать сервер Express и заставить наше приложение прослушивать номер порта приложения вместе с запросом на тестовый маршрут — /test. Обновим app.js, под операторами импорта:


const app = express();
const port = process.env.PORT || 4000;

app.get("/test", async (req, res) => {
    return res.status(200).json({ success: true });
});

app.listen(port, () => {
    console.log(`Server is running at port ${port}`);
});

С этого момента мы узнаем, как обрабатывать различные варианты использования операционных ошибок, которые могут возникнуть в Express.

Обработка ошибок Not Found в Express

Предположим, вам нужно получить всех пользователей из базы данных пользователей, вы можете эффективно справиться с потенциальным сценарием ошибки, когда в базе данных нет данных, обернув логику в try/catch блокировать — в надежде поймать любую ошибку, которая может возникнуть в catch Блок:


const getUser = () => undefined;

app.get("/get-user", async (req, res) => {
	try {
		const user = getUser();
		if (!user) {
			throw new Error('User not found');
		}
	} catch (error) {
	    
		console.log(error); 
		
		res.status(400).send(error.message) 
	}
	return res.status(200).json({
		success: true
	});
});

Это приводит к:

User not found

Теперь, когда этот запрос сделан (вы можете проверить с помощью Postman), а в базе данных нет пользователя, клиент получает сообщение об ошибке «Пользователь не найден». Кроме того, вы заметите, что ошибка также регистрируется в консоли.

Оптимизация обработки ошибок с помощью ПО промежуточного слоя обработчика ошибок

Мы можем оптимизировать разработку, создав промежуточное программное обеспечение для обработки ошибок, которое будет находиться в конце всех определенных маршрутов, так что, если на одном из маршрутов возникает ошибка, Express автоматически просматривает следующее промежуточное программное обеспечение и продолжает двигаться вниз по списку. пока не достигнет обработчика ошибок. Обработчик ошибок обработает ошибку, а также отправит ответ клиенту.

Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!

Для начала создайте папку с именем middleware в каталоге проекта и в этой папке создайте файл с именем errorHandler.js который определяет обработчик ошибок:

const errorHandler = (error, req, res, next) => {
    
    console.log(error); 
    
    res.status(400).send(error.message); 
}
module.exports = errorHandler;

В нашей промежуточной функции мы дали Express понять, что это не базовая промежуточная функция, а обработчик ошибок, добавив error перед тремя основными параметрами.

Теперь мы будем использовать обработчик ошибок в нашей демонстрации. app.js и обработайте первоначальную ошибку выборки пользователей с помощью промежуточного программного обеспечения обработчика ошибок, как показано ниже:


const getUser = () => undefined;

app.get("/get-user", async (req, res, next) => {
	try {
		const user = getUser();
		if (!user) {
			throw new Error("User not found");
		}
	} catch (error) {
		return next(error);
	}
});

app.use(errorHandler);

Мы можем еще больше оптимизировать наш код, создав абстракцию вокруг try/catch логика. Мы можем добиться этого, создав новую папку в каталоге проекта с именем utils, и в нем создайте файл с именем tryCatch.js.

Чтобы абстрагироваться от try-catch логика — мы можем определить функцию, которая принимает другую функцию (известную как контроллер) в качестве параметра и возвращает async функция, которая будет содержать try/catch для любого полученного контроллера.

Если в контроллере возникает ошибка, она фиксируется в catch блок и вызывается следующая функция:


const tryCatch = (controller) => async (req, res, next) => {
	try {
		await controller(req, res);
	} catch (error) {
		return next(error);
	}
};
module.exports = tryCatch;

Для try/catch абстракция, мы можем реорганизовать наш код, чтобы сделать его более кратким, пропуская try-catch предложение явно при выборке пользователей в app.js:


const getUser = () => undefined;

app.get(
	"/get-user",
	tryCatch(async (req, res) => {
		const user = getUser();
		if (!user) {
			throw new Error("User not found");
		}
		res.status(400).send(error.message);
	})
);

Мы успешно абстрагировались от логики try-catch, и наш код по-прежнему работает так же, как и раньше.

Обработка ошибок проверки в Express

Для этой демонстрации мы создадим новый маршрут в нашем приложении Express для входа в систему — для проверки идентификатора пользователя при входе в систему. Сначала мы установим joi package, чтобы помочь с созданием схемы, с помощью которой мы можем обеспечить соблюдение требований:

$ npm i joi

Далее создайте схему, которая Joi.object с userId который должен быть числом и является обязательным — это означает, что запрос должен соответствовать объекту с идентификатором пользователя.

Мы можем использовать validate() метод в объекте схемы для проверки каждого ввода по схеме:


const schema = Joi.object({
	userId: Joi.number().required(),
});

app.post(
	"/login",
	tryCatch(async (req, res) => {
		const {error, value} = schema.validate({});
		if (error) throw error;
	})
);

Если пустой объект передается в validate() метод, ошибка будет изящно обработана, и сообщение об ошибке будет отправлено клиенту:

На консоли мы также получаем доступ к details массив, который включает в себя различные сведения об ошибке, которые могут быть сообщены пользователю в случае необходимости.

Чтобы специально обрабатывать ошибки проверки таким образом, чтобы передавать соответствующие сведения об ошибке для каждой ошибки проверки, промежуточное программное обеспечение обработчика ошибок может быть реорганизовано:


const errorHandler = (error, req, res, next) => {
	console.log(error); 

	if (error.name === "ValidationError") {
		return res.status(400).send({
			type: "ValidationError",
			details: error.details,
		});
	}

	res.status(400).send(error.message); 
};

module.exports = errorHandler;

Доступно errorHandler.js теперь настроено, когда мы делаем тот же запрос с пустым объектом, переданным в validate() Метод:

Руководство по обработке исключений в Express PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Теперь у нас есть доступ к настроенному объекту, который возвращает сообщения в более читаемом/дружественном виде. Таким образом, мы можем отправлять и обрабатывать различные типы ошибок в зависимости от типа поступающей ошибки.

Заключение

В этом руководстве мы рассмотрели все аспекты обработки ошибок в Express.js, в том числе то, как синхронный и асинхронный код обрабатывается по умолчанию, как создавать собственные классы ошибок, как писать собственные функции промежуточного программного обеспечения для обработки ошибок и предоставлять next как последний обработчик catch

Как и в случае с любой другой задачей, во время разработки также используются передовые методы, в том числе эффективная обработка ошибок, и сегодня мы узнали, как мы можем надежно обрабатывать ошибки в приложении Express.

Правильная обработка ошибок означает не только сокращение времени разработки за счет легкого поиска багов и ошибок, но и разработку надежной кодовой базы для крупномасштабных приложений. В этом руководстве мы увидели, как настроить промежуточное ПО для обработки операционных ошибок. Некоторые другие способы улучшить обработку ошибок включают в себя: отказ от отправки трассировки стека, изящную остановку процессов для обработки неперехваченных исключений, предоставление соответствующих сообщений об ошибках, отправку журналов ошибок и настройку класса, который расширяет Error класса.

Я надеюсь, что примеры, которые я использовал в этом уроке, были вам интересны. Я рассмотрел различные сценарии управления ошибками, с которыми вы потенциально можете столкнуться при написании приложения Express для использования в реальном мире. Пожалуйста, дайте мне знать, если я что-то пропустил. Это принесет пользу нам и поможет мне узнать больше. Хорошего дня и спасибо за чтение.

Вы можете обратиться ко всему исходному коду, использованному в статье, на Github.

Дополнительные ресурсы

Отметка времени:

Больше от Стекабьюс