Ajusta proxy local e erros da API
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
:80 {
|
:80 {
|
||||||
encode gzip zstd
|
encode gzip zstd
|
||||||
|
|
||||||
|
handle_path /api/* {
|
||||||
|
reverse_proxy backend:8082
|
||||||
|
}
|
||||||
|
|
||||||
handle {
|
handle {
|
||||||
reverse_proxy frontend:80
|
reverse_proxy frontend:80
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${CADDY_HTTP_PORT:-8088}:80"
|
- "127.0.0.1:${CADDY_HTTP_PORT:-8088}:80"
|
||||||
- "127.0.0.1:${CADDY_HTTPS_PORT:-8443}:443"
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
- caddy_data:/data
|
- caddy_data:/data
|
||||||
|
|||||||
+28
-1
@@ -30,6 +30,16 @@ export class ApiError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getApiErrorMessage(error: unknown) {
|
||||||
|
if (error instanceof ApiError) {
|
||||||
|
return "Erro " + error.status + ": " + error.message;
|
||||||
|
}
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return error.message;
|
||||||
|
}
|
||||||
|
return "Falha na comunicação com a API";
|
||||||
|
}
|
||||||
|
|
||||||
async function apiRequest<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
async function apiRequest<T>(path: string, options: RequestOptions = {}): Promise<T> {
|
||||||
const url = buildApiUrl(path);
|
const url = buildApiUrl(path);
|
||||||
Object.entries(options.params ?? {}).forEach(([key, value]) => {
|
Object.entries(options.params ?? {}).forEach(([key, value]) => {
|
||||||
@@ -51,7 +61,7 @@ async function apiRequest<T>(path: string, options: RequestOptions = {}): Promis
|
|||||||
setAuthToken(null);
|
setAuthToken(null);
|
||||||
}
|
}
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const detail = await response.text();
|
const detail = await readErrorMessage(response);
|
||||||
throw new ApiError(detail || "Falha na comunicação com a API", response.status);
|
throw new ApiError(detail || "Falha na comunicação com a API", response.status);
|
||||||
}
|
}
|
||||||
if (response.status === 204) {
|
if (response.status === 204) {
|
||||||
@@ -60,6 +70,23 @@ async function apiRequest<T>(path: string, options: RequestOptions = {}): Promis
|
|||||||
return response.json() as Promise<T>;
|
return response.json() as Promise<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function readErrorMessage(response: Response) {
|
||||||
|
const contentType = response.headers.get("Content-Type") ?? "";
|
||||||
|
const text = await response.text();
|
||||||
|
if (!text) {
|
||||||
|
return response.statusText;
|
||||||
|
}
|
||||||
|
if (contentType.includes("application/json")) {
|
||||||
|
try {
|
||||||
|
const json = JSON.parse(text) as { message?: string; detail?: string; error?: string; title?: string };
|
||||||
|
return json.message ?? json.detail ?? json.error ?? json.title ?? text;
|
||||||
|
} catch {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
function buildApiUrl(path: string) {
|
function buildApiUrl(path: string) {
|
||||||
if (API_BASE_URL.startsWith("http://") || API_BASE_URL.startsWith("https://")) {
|
if (API_BASE_URL.startsWith("http://") || API_BASE_URL.startsWith("https://")) {
|
||||||
return new URL(path, API_BASE_URL);
|
return new URL(path, API_BASE_URL);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Button } from "../components/ui/button";
|
|||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/ui/card";
|
||||||
import { Input } from "../components/ui/input";
|
import { Input } from "../components/ui/input";
|
||||||
import { Select } from "../components/ui/select";
|
import { Select } from "../components/ui/select";
|
||||||
import { api } from "../lib/api";
|
import { api, getApiErrorMessage } from "../lib/api";
|
||||||
|
|
||||||
export function NovaBuscaPage() {
|
export function NovaBuscaPage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -93,7 +93,7 @@ export function NovaBuscaPage() {
|
|||||||
{formError && <p className="mt-2 text-sm text-destructive">{formError}</p>}
|
{formError && <p className="mt-2 text-sm text-destructive">{formError}</p>}
|
||||||
{criarBusca.isError && (
|
{criarBusca.isError && (
|
||||||
<p className="mt-2 text-sm text-destructive">
|
<p className="mt-2 text-sm text-destructive">
|
||||||
Não foi possível criar a busca. Atualize a página e tente novamente.
|
Não foi possível criar a busca. {getApiErrorMessage(criarBusca.error)}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user