# Hibák gyűjtése ErrorBuilderrel, naplózásuk ERROR()-ral és audit nyom vezetése AUDIT()-tal

> Válaszoljon egyszerre több hibával az ErrorBuilderrel, a SUCCESS() válasszal, és ismerje meg, hogyan jegyzi fel az ERROR() a hibákat, és hogyan fűzi hozzá az AUDIT() egy naplófájlhoz, ki mit tett.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: hu
Content-SHA256: 9f4bf33484dea42f763e5f47cc5fa376d6bafbea40ab9fe2bc4b417641ab603b
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

- Az **`ErrorBuilder`** hibákat gyűjt. A `push(message, [path], [index])` hozzáad egyet (a `path` a mező, amelyhez tartozik), a `push(404)` hozzáadja egy állapotkód szövegét és beállítja a válasz állapotát, a `length` megszámolja őket, az `output()` `{ error, path, index }` tömbként adja vissza őket, a `toString()` pedig összefűzi az üzeneteket. A `$.invalid(builder)` ezzel a tömbbel és a builder állapotával válaszol (400, hacsak nem adtak hozzá állapotkódot).
- A **`SUCCESS(value)`** egy sikeres művelet objektumát adja vissza: `{ success: true, value: value }`.
- Az **`ERROR(name)`** egy callbacket ad vissza a `function(err)` típusú API-khoz: ha hibát kap, `name` néven feljegyzi, és nem tesz semmit, ha a hiba üres. Az `ERROR()` ugyanez a callback név nélkül. A feljegyzett hiba megjelenik a konzolon, beleszámít az `F.stats.error`-ba, az utolsó tíz pedig az `F.errors`-ban marad `{ error, name, date }` alakban.
- Az **`AUDIT($, message, type)`** egy JSON sort fűz a `logs/audit.log`-hoz azzal, hogy ki és hol (`ip`, `ua`, `url`, és a felhasználó, ha van), a `message`, a `type`, a kérés `params`, `query` és `model` értékei a `data` mezőben, az alkalmazás neve az `app` mezőben és az idő a `dtcreated` mezőben. Az `AUDIT('name', $, message, type)` helyette a `logs/name.log` fájlba ír.

```js controllers/reports.js
exports.install = function() {
	ROUTE('GET /builder/', builder);
	ROUTE('GET /builder404/', builder404);
	ROUTE('GET /success/', success);
	ROUTE('GET /error/', error);
	ROUTE('GET /audit/', audit);
	ROUTE('GET /audit-read/{name}/', auditread);
};

function builder($) {
	const errors = new ErrorBuilder();
	errors.push('Name is required', 'name');
	errors.push('Age is too low', 'age', 2);
	$.invalid(errors);
}

function builder404($) {
	const errors = new ErrorBuilder();
	errors.push(404);
	$.invalid(errors);
}

function success($) {
	$.json(SUCCESS('saved'));
}

function error($) {
	const before = F.stats.error;
	ERROR('mypart')('Something broke');
	ERROR('mypart')(null);
	ERROR()('Without a name');
	$.json({ counted: F.stats.error - before, last: F.errors.slice(-2).map(n => ({ error: n.error, name: n.name || null, date: n.date instanceof Date || typeof n.date === 'string' })) });
}

function audit($) {
	AUDIT($, 'Opened the report', 'info');
	AUDIT('security', $, 'Checked the access');
	$.json({ ok: true });
}

function auditread($) {
	setTimeout(function() {
		const lines = require('fs').readFileSync(PATH.logs($.params.name + '.log'), 'utf8').trim().split('\n');
		$.json(lines.map(n => JSON.parse(n)));
	}, 300);
}
```
