# Personalizar as páginas 404 e 401

> Registe handlers ROUTE('#404') e ROUTE('#401') para substituir as páginas de erro incorporadas e dispare-os você mesmo com $.fallback().

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: pt
Content-SHA256: 40f89999c8ee8aba930d873a2ac160eb71144130fb5bfbcc566a6920c5f6d151
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Quando o Total.js não consegue atender um pedido, mostra uma página de erro incorporada. Uma rota cujo URL é `#` mais o código de estado substitui-a: `ROUTE('#404', fn)` para "não encontrado", `ROUTE('#401', fn)` para "não autorizado", e o mesmo para `#400`, `#431` e outros. O handler recebe `$` como qualquer rota, mas **o estado é você que o define** com `$.response.status`: o Total.js não o faz por si quando existe um handler próprio. Sem handler próprio usa-se a página incorporada e os pedidos AJAX (cabeçalho `x-requested-with`) recebem um erro JSON em vez de HTML.

`$.fallback(code)` envia o pedido atual para o handler de `code`, que é a forma de responder 404 para um registo que não existe ou 403 para um recurso proibido a partir do seu próprio código.

```js controllers/errors.js
exports.install = function() {
	ROUTE('#404', not_found);
	ROUTE('#401', unauthorized);
	ROUTE('GET /items/{id}/', item);
	ROUTE('+GET /private/', private_page);
};

var items = { '1': 'First item' };

function item($) {
	var name = items[$.params.id];
	if (name)
		$.json({ name: name });
	else
		$.fallback(404);
}

function private_page($) {
	$.plain('secret');
}

function not_found($) {
	$.response.status = 404;
	$.html('<h1>Nothing here</h1><p>' + $.url.encode() + ' does not exist.</p>');
}

function unauthorized($) {
	$.response.status = 401;
	$.json({ error: 'Please sign in first' });
}

AUTH(function($) {
	$.invalid();
});
```
