Tratamento de erros da API

This commit is contained in:
Eduarda-SS 2025-09-24 17:27:18 -03:00
parent 282b2ea1c9
commit 06905af34d
8 changed files with 353 additions and 51 deletions

View File

@ -0,0 +1,10 @@
export async function handleApiResponse(response) {
const data = await response.json();
if (!response.ok) {
// Throw the full error object (parsed JSON) so catch can handle it
throw data;
}
return data; // Success case
}

View File

@ -1,23 +1,56 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import avatarPlaceholder from '../assets/images/avatar_placeholder.png'; import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
import handleApiResponse from '../assets/utils/apiHandler';
const Details = ({ patientID, setCurrentPage }) => { const Details = ({ patientID, setCurrentPage }) => {
const [paciente, setPaciente] = useState({}); const [paciente, setPaciente] = useState({});
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
useEffect(() => { useEffect(() => {
if (!patientID) return; if (!patientID) return;
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`) fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`)
.then(res => res.json()) .then(res => res.json())
// .then(result => {setPaciente(result.data)})
.then(result => {setPaciente(result.data)}) // .catch(err => console.error("Erro ao buscar paciente:", err));
.catch(err => console.error("Erro ao buscar paciente:", err)); .then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}, [patientID]); }, [patientID]);
//if (!paciente) return <p style={{ textAlign: "center" }}>Carregando...</p>;
return ( return (
<> <>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="card p-3 shadow-sm"> <div className="card p-3 shadow-sm">
<h3 className="mb-3 text-center">MediConnect</h3> <h3 className="mb-3 text-center">MediConnect</h3>
<hr /> <hr />

View File

@ -1,22 +1,56 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import avatarPlaceholder from '../assets/images/avatar_placeholder.png'; import avatarPlaceholder from '../assets/images/avatar_placeholder.png';
import handleApiResponse from '../assets/utils/apiHandler';
const Details = ({ patientID, setCurrentPage }) => { const Details = ({ patientID, setCurrentPage }) => {
const [paciente, setPaciente] = useState({}); const [paciente, setPaciente] = useState({});
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
useEffect(() => { useEffect(() => {
if (!patientID) return; if (!patientID) return;
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`) fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`)
.then(res => res.json()) .then(res => res.json())
.then(data => setPaciente(data)) // .then(data => setPaciente(data))
.catch(err => console.error("Erro ao buscar médico:", err)); // .catch(err => console.error("Erro ao buscar médico:", err));
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}, [patientID]); }, [patientID]);
//if (!paciente) return <p style={{ textAlign: "center" }}>Carregando...</p>; //if (!paciente) return <p style={{ textAlign: "center" }}>Carregando...</p>;
return ( return (
<> <>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="card p-3 shadow-sm"> <div className="card p-3 shadow-sm">
<h3 className="mb-3 text-center">MediConnect</h3> <h3 className="mb-3 text-center">MediConnect</h3>
<hr /> <hr />

View File

@ -1,12 +1,12 @@
import React from 'react' import React from 'react'
import DoctorForm from '../components/doctors/DoctorForm' import DoctorForm from '../components/doctors/DoctorForm'
import handleApiResponse from '../assets/utils/apiHandler';
import {useEffect, useState} from 'react' import {useEffect, useState} from 'react'
const DoctorEditPage = ( {id}) => { const DoctorEditPage = ( {id}) => {
const [PatientToPUT, setPatientPUT] = useState({}) const [PatientToPUT, setPatientPUT] = useState({})
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
var requestOptions = { var requestOptions = {
method: 'GET', method: 'GET',
@ -14,15 +14,51 @@ const DoctorEditPage = ( {id}) => {
}; };
useEffect(() => { useEffect(() => {
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions) fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
.then(response => response.json()) .then(response => response.json())
.then(result => result.data) // .then(result => result.data)
.then(data => console.log(data)) // .then(data => console.log(data))
.catch(error => console.log('error', error)); // .catch(error => console.log('error', error));
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
// .then(async (response) => {
// const data = await response.json();
// if (!response.ok) {
// // response is 400, 401, 500 etc.
// throw data; // throw the parsed JSON error so it goes to catch
// }
// return data; // return success data
// })
// .then((result) => {
// console.log("Success data:", result);
// // here you would setState with result
// })
// .catch((error) => {
// // error is the parsed JSON from the API
// console.error("API error:", error);
// // Example: show main message
// alert(error.message);
// // Example: show field errors if available
// if (error.details) {
// Object.entries(error.details).forEach(([field, messages]) => {
// console.log(`${field}:`, messages);
// });
// }
// });
}, []) }, [])
const HandlePutPatient = () => { const HandlePutPatient = () => {
console.log('médico atualizado') console.log('médico atualizado')
@ -33,7 +69,27 @@ fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOpt
return ( return (
<div> <div>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}

View File

@ -1,9 +1,12 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import handleApiResponse from '../assets/utils/apiHandler';
function TableDoctor({ setCurrentPage, setPatientID }) { function TableDoctor({ setCurrentPage, setPatientID }) {
const [medicos, setMedicos] = useState([]); const [medicos, setMedicos] = useState([]);
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [filtroAniversariante, setFiltroAniversariante] = useState(false); const [filtroAniversariante, setFiltroAniversariante] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
// Função para excluir médicos // Função para excluir médicos
const deleteDoctor = async (id) => { const deleteDoctor = async (id) => {
@ -16,8 +19,18 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
requestOptionsDelete requestOptionsDelete
) )
.then((response) => response.text()) .then((response) => response.text())
.then((mensage) => console.log(mensage)) // .then((mensage) => console.log(mensage))
.catch((error) => console.log("Deu problema", error)); // .catch((error) => console.log("Deu problema", error));
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}; };
// Função para verificar se hoje é aniversário // Função para verificar se hoje é aniversário
@ -36,10 +49,20 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
useEffect(() => { useEffect(() => {
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes") fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
.then((response) => response.json()) .then((response) => response.json())
.then((result) => setMedicos(result["data"])) // .then((result) => setMedicos(result["data"]))
.catch((error) => // .catch((error) =>
console.log("Erro para encontrar médicos no banco de dados", error) // console.log("Erro para encontrar médicos no banco de dados", error)
); // );
.then(handleApiResponse)
.then((data) => {
setMedicos(result[data]);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}, []); }, []);
// Filtrar médicos pelo campo de pesquisa e aniversariantes // Filtrar médicos pelo campo de pesquisa e aniversariantes
@ -53,6 +76,27 @@ function TableDoctor({ setCurrentPage, setPatientID }) {
return ( return (
<> <>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="page-heading"> <div className="page-heading">
<h3>Lista de Médicos</h3> <h3>Lista de Médicos</h3>
</div> </div>

View File

@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import PatientForm from '../components/patients/PatientForm'
import {useEffect, useState} from 'react' import {useEffect, useState} from 'react'
import PatientForm from '../components/patients/PatientForm'
import handleApiResponse from '../assets/utils/apiHandler';
const EditPage = ( {id}) => { const EditPage = ( {id}) => {
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
const [PatientToPUT, setPatientPUT] = useState({}) const [PatientToPUT, setPatientPUT] = useState({})
var requestOptions = { var requestOptions = {
@ -18,9 +18,19 @@ useEffect(() => {
fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions) fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions)
.then(response => response.json()) .then(response => response.json())
.then(result => result.data) // .then(result => result.data)
.then(data => setPatientPUT(data)) // .then(data => setPatientPUT(data))
.catch(error => console.log('error', error)); // .catch(error => console.log('error', error));
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}, []) }, [])
@ -43,8 +53,18 @@ var requestOptions = {
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/", requestOptions) fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/", requestOptions)
.then(response => response.text()) .then(response => response.text())
.then(result => console.log('ATUALIZADO COM SUCESSO',result)) // .then(result => console.log('ATUALIZADO COM SUCESSO',result))
.catch(error => console.log('error', error)); // .catch(error => console.log('error', error));
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
} }
@ -52,7 +72,27 @@ fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/", requestOptions)
return ( return (
<div> <div>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<PatientForm <PatientForm

View File

@ -5,25 +5,47 @@ import './style/Inicio.css';
function Inicio({ setCurrentPage }) { function Inicio({ setCurrentPage }) {
const [pacientes, setPacientes] = useState([]); const [pacientes, setPacientes] = useState([]);
const [agendamentos, setAgendamentos] = useState([]); const [agendamentos, setAgendamentos] = useState([]);
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
useEffect(() => { useEffect(() => {
const fetchPacientes = async () => { const fetchPacientes = async () => {
try { try {
const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes"); const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes");
if (!response.ok) {
const errorData = await response.json();
setErrorMessage(errorData.message || "Erro desconhecido");
if (errorData.details) {
setFieldErrors(errorData.details);
}
return;
}
const data = await res.json(); const data = await res.json();
setPacientes(data.data); setPacientes(data.data);
setErrorMessage("");
setFieldErrors({});
} catch (error) { } catch (error) {
console.error("Erro ao buscar pacientes:", error); console.error("Erro ao buscar pacientes:", error);
setErrorMessage("Falha na comunicação com o servidor");
} }
}; };
const fetchAgendamentos = async () => { const fetchAgendamentos = async () => {
try { try {
const res = await fetch(); const res = await fetch();
if (!response.ok) {
const errorData = await response.json();
setErrorMessage(errorData.message || "Erro desconhecido");
if (errorData.details) {
setFieldErrors(errorData.details);
}
return;
}
const data = await res.json(); const data = await res.json();
setAgendamentos(data.data); setAgendamentos(data.data);
} catch (error) { } catch (error) {
console.error("Erro ao buscar agendamentos:", error); console.error("Erro ao buscar agendamentos:", error);
setErrorMessage("Falha na comunicação com o servidor");
} }
}; };
@ -48,6 +70,28 @@ function Inicio({ setCurrentPage }) {
</div> </div>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="stats-grid"> <div className="stats-grid">
<div className="stat-card"> <div className="stat-card">
<div className="stat-info"> <div className="stat-info">

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import handleApiResponse from '../assets/utils/apiHandler';
function TablePaciente({ setCurrentPage, setPatientID }) { function TablePaciente({ setCurrentPage, setPatientID }) {
const [pacientes, setPacientes] = useState([]); const [pacientes, setPacientes] = useState([]);
@ -6,7 +7,8 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
const [filtroConvenio, setFiltroConvenio] = useState("Todos"); const [filtroConvenio, setFiltroConvenio] = useState("Todos");
const [filtroVIP, setFiltroVIP] = useState(false); const [filtroVIP, setFiltroVIP] = useState(false);
const [filtroAniversariante, setFiltroAniversariante] = useState(false); const [filtroAniversariante, setFiltroAniversariante] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
const [fieldErrors, setFieldErrors] = useState({});
const GetAnexos = async (id) => { const GetAnexos = async (id) => {
var myHeaders = new Headers(); var myHeaders = new Headers();
@ -20,29 +22,32 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
try { try {
const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}/anexos`, requestOptions); const response = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}/anexos`, requestOptions);
const result = await response.json(); const result = await response.json();
if (!response.ok) {
const errorData = await response.json();
setErrorMessage(errorData.message || "Erro desconhecido");
if (errorData.details) {
setFieldErrors(errorData.details);
}
return;
}
setErrorMessage("");
setFieldErrors({});
return result.data; // agora retorna corretamente return result.data; // agora retorna corretamente
} catch (error) { } catch (error) {
console.log('error', error); console.log('error', error);
setErrorMessage("Falha na comunicação com o servidor");
return []; return [];
} }
} }
const DeleteAnexo = async (patientID) => { const DeleteAnexo = async (patientID) => {
const RespostaGetAnexos = await GetAnexos(patientID)
const RespostaGetAnexos = await GetAnexos(patientID)
for(let i = 0; i < RespostaGetAnexos.length; i++){ for(let i = 0; i < RespostaGetAnexos.length; i++){
const idAnexo = RespostaGetAnexos[i].id; const idAnexo = RespostaGetAnexos[i].id;
console.log('anexos',RespostaGetAnexos) console.log('anexos',RespostaGetAnexos)
var myHeaders = new Headers(); var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer <token>"); myHeaders.append("Authorization", "Bearer <token>");
@ -69,9 +74,6 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
DeleteAnexo(id) DeleteAnexo(id)
const requestOptionsDelete = { method: "DELETE", redirect: "follow" }; const requestOptionsDelete = { method: "DELETE", redirect: "follow" };
if (!window.confirm("Tem certeza que deseja excluir este paciente?")) return; if (!window.confirm("Tem certeza que deseja excluir este paciente?")) return;
@ -117,22 +119,40 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
} }
) )
.then((response) => response.json()) .then((response) => response.json())
.then(handleApiResponse)
.then(() => { .then(() => {
setPacientes((prev) => setPacientes((prev) =>
prev.map((p) => (p.id === id ? { ...p, convenio } : p)) prev.map((p) => (p.id === id ? { ...p, convenio } : p))
); );
setErrorMessage("");
setFieldErrors({});
}) })
.catch((error) => console.log("Erro ao atualizar convênio:", error)); // .catch((error) => console.log("Erro ao atualizar convênio:", error));
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}; };
// Requisição inicial para buscar pacientes // Requisição inicial para buscar pacientes
useEffect(() => { useEffect(() => {
fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes") fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes")
.then((response) => response.json()) // .then((response) => response.json())
.then((result) => setPacientes(result["data"])) // .then((result) => setPacientes(result["data"]))
.catch((error) => // .catch((error) =>
console.log("Erro para encontrar pacientes no banco de dados", error) // console.log("Erro para encontrar pacientes no banco de dados", error)
); // );
.then(handleApiResponse)
.then((data) => {
setPaciente(data);
setErrorMessage("");
setFieldErrors({});
})
.catch((error) => {
setErrorMessage(error.message || "Erro desconhecido");
setFieldErrors(error.details || {});
});
}, []); }, []);
// Função para verificar se hoje é aniversário do paciente // Função para verificar se hoje é aniversário do paciente
@ -167,6 +187,27 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
<div className="page-heading"> <div className="page-heading">
<h3>Lista de Pacientes</h3> <h3>Lista de Pacientes</h3>
</div> </div>
{errorMessage && (
<div style={{ color: "red", marginBottom: "1rem" }}>
{errorMessage}
</div>
)}
{/* Mensagens de erro específicas */}
{Object.keys(fieldErrors).length > 0 && (
<div style={{ color: "darkred", marginBottom: "1rem" }}>
{Object.entries(fieldErrors).map(([campo, mensagens]) => (
<div key={campo}>
<strong>{campo}:</strong>
<ul>
{mensagens.map((msg, idx) => (
<li key={idx}>{msg}</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="page-content"> <div className="page-content">
<section className="row"> <section className="row">
<div className="col-12"> <div className="col-12">