Commit 66f8b350 authored by Giridhari Sahoo's avatar Giridhari Sahoo

error handling implementation

parent 4e7dccae
......@@ -3,7 +3,12 @@ package com.nisum.Employeeinfo.dao;
import com.nisum.Employeeinfo.errorcode.ApiErrorCode;
import com.nisum.Employeeinfo.exception.EmployeeNotFoundException;
import com.nisum.Employeeinfo.model.Employee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.r2dbc.BadSqlGrammarException;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
......@@ -12,6 +17,8 @@ import reactor.core.publisher.Mono;
@Repository
public class EmployeeDao {
private static final Logger log = LoggerFactory.getLogger(EmployeeDao.class);
@Autowired
private DatabaseClient databaseClient;
......@@ -25,13 +32,24 @@ public class EmployeeDao {
.bind("sal",employee.getSal())
.fetch()
.rowsUpdated()
.flatMap(rows->{
if (rows>0){
return Mono.just(employee);
}else {
return Mono.error(new EmployeeNotFoundException(ApiErrorCode.EMPLOYEE_NOT_FOUND,"Employee Not Found"));
.flatMap(rows -> {
if (rows > 0) {
// Successfully inserted the employee
return Mono.just(employee)
.doOnSuccess(savedEmployee -> {
// Side effect: log successful insert
log.info("Successfully saved employee: {}", savedEmployee);
});
} else {
// No rows updated, employee not found (error scenario)
return Mono.error(new EmployeeNotFoundException(ApiErrorCode.EMPLOYEE_NOT_FOUND, "Employee Not Found"));
}
})
.onErrorResume(RuntimeException.class,ex->{
log.error("invalid employee data {}",ex.getMessage());
return Mono.just(new Employee(-1,"invalid name","invalid email","invalid dept",0.0));
});
}
public Flux<Employee> findAllEmployee(){
String query="SELECT * FROM employee ";
......@@ -43,7 +61,13 @@ public class EmployeeDao {
row.get("dept",String.class),
row.get("sal",Double.class)
))
.all();
.all()
.doOnComplete(()->log.info("Successfully fetched all the employees"))
.doOnError(err->log.error("Error in Fetching the Employee Records {}",err.getMessage()))
.onErrorResume(BadSqlGrammarException.class, ex->{
log.error("No data found {}",ex.getMessage());
return Flux.empty();
});
}
......@@ -59,7 +83,14 @@ public class EmployeeDao {
row.get("dept", String.class),
row.get("sal", Double.class)
))
.one();
.one()
.doOnSuccess(employee -> log.info("Successfully fetched employee: {}", employee))
.doOnError(error -> log.error("Error fetching employee with ID {}: {}", id, error.getMessage()))
.onErrorResume(EmptyResultDataAccessException.class, ex -> {
// Handle the case where no employee is found (returning empty)
log.warn("No employee found with ID: {}", id);
return Mono.empty(); // Return an empty Mono
});
}
public Mono<Employee> updateEmployee(Integer id,Employee employee){
String query = "UPDATE employee SET name = :name, email = :email, dept = :dept, sal = :sal WHERE id = :id";
......@@ -81,6 +112,15 @@ public class EmployeeDao {
// Return an error if no rows were updated (e.g., employee not found)
return Mono.error(new RuntimeException("Employee with ID " + id + " not found"));
}
})
.doOnSuccess(updatedEmployee -> log.info("Employee updated successfully: {}", updatedEmployee))
.doOnError(error -> log.error("Error updating employee with ID {}: {}", id, error.getMessage()))
.onErrorReturn(RuntimeException.class, new Employee(0, "Unknown", "unknown@domain.com", "Unknown", 0.0))
.onErrorContinue((throwable, o) -> {
if (throwable instanceof RuntimeException) {
// Log and continue if a RuntimeException occurs
log.warn("Continuing despite error: {}", throwable.getMessage());
}
});
}
......@@ -97,6 +137,9 @@ public class EmployeeDao {
return Mono.error(new EmployeeNotFoundException(ApiErrorCode.EMPLOYEE_NOT_FOUND,"Employee_Not_Found"));
}
});
}
......
......@@ -10,6 +10,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.*;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
......@@ -106,25 +107,37 @@ public class EmployeeControllerTest {
@Test
public void updateEmployeeTest(){
Integer id=1;
EmployeeDto employeeDto = new EmployeeDto("sam", "sam@gmail.com", "IT", 28000.00);
Employee updateEmployee = new Employee(1, "sam", "sam@gmail.com", "IT", 28000.00);
Mockito.when(validator.isEmployeeIdValid(anyInt())).thenReturn(Mono.just(Boolean.TRUE));
Mockito.when(validator.isEmployeeNameValid(any())).thenReturn(Mono.just(Boolean.TRUE));
Mockito.when(validator.isEmployeeSalaryValid(anyDouble())).thenReturn(Mono.just(Boolean.TRUE));
Mockito.when(employeeService.updateEmployee(ArgumentMatchers.eq(1),ArgumentMatchers.any())).thenReturn(Mono.just(updateEmployee));
Mockito.when(validator.isEmployeeIdValid(id)).thenReturn(Mono.just(true));
Mockito.when(validator.isEmployeeNameValid(employeeDto.getName())).thenReturn(Mono.just(true));
Mockito.when(validator.isEmployeeSalaryValid(employeeDto.getSal())).thenReturn(Mono.just(true));
Mockito.when(employeeService.updateEmployee(id,Mono.just(employeeDto) )).thenReturn(Mono.just(updateEmployee));
// Call controller method
Mono<ResponseEntity<Employee>> responseMono = employeeController.updateEmployee(id, Mono.just(employeeDto));
StepVerifier.create(employeeController.updateEmployee(ArgumentMatchers.eq(1),Mono.just(employeeDto)))
.expectNextMatches(response->{
// Verify response
StepVerifier.create(responseMono)
.expectNextMatches(response -> {
Employee employee = response.getBody();
return response.getStatusCode().is2xxSuccessful()
&& response.getBody() != null
&& response.getBody().getId().equals(1)
&& "sam".equals(response.getBody().getName())
&& "sam@gmail.com".equals(response.getBody().getEmail())
&& "IT".equals(response.getBody().getDept())
&& Double.compare(response.getBody().getSal(), 28000.00) == 0 ;
}).verifyComplete();
&& employee.getId().equals(updateEmployee.getId())
&& employee.getName().equals(updateEmployee.getName())
&& employee.getEmail().equals(updateEmployee.getEmail())
&& employee.getDept().equals(updateEmployee.getDept())
&& Double.compare(employee.getSal(), updateEmployee.getSal()) == 0;
})
.verifyComplete();
// Verify interactions
Mockito.verify(validator, Mockito.times(1)).isEmployeeIdValid(id);
Mockito.verify(validator, Mockito.times(1)).isEmployeeNameValid(updateEmployee.getName());
Mockito.verify(validator, Mockito.times(1)).isEmployeeSalaryValid(updateEmployee.getSal());
Mockito.verify(employeeService, Mockito.times(1)).updateEmployee(Mockito.eq(id), Mono.just(employeeDto));
}
......
package com.nisum.Employeeinfo.dao;
import com.nisum.Employeeinfo.model.Employee;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.r2dbc.core.DatabaseClient;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@SpringBootTest
public class EmployeeDaoTest {
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@InjectMocks
private EmployeeDao employeeDao;
@Mock
private DatabaseClient databaseClient;
@Mock
private DatabaseClient.GenericExecuteSpec executeSpec;
}
//@SpringBootTest
//public class EmployeeDaoTest {
//
// @InjectMocks
// private EmployeeDao employeeDao;
//
// @Mock
// private DatabaseClient databaseClient;
//
// @Mock
// private DatabaseClient.GenericExecuteSpec executeSpec;
//
//// @Mock
//// private DatabaseClient.GenericFetchSpec fetchSpec;
//
//
// private final Employee mockEmployee = new Employee(1, "Rahul", "rahul@gmail.com", "IT", 50000.00);
//
// @Test
// void saveEmployee_Success() {
// // Arrange
// when(databaseClient.sql(anyString())).thenReturn(executeSpec);
// when(executeSpec.bind(eq("name"), eq(mockEmployee.getName()))).thenReturn(executeSpec);
// when(executeSpec.bind(eq("email"), eq(mockEmployee.getEmail()))).thenReturn(executeSpec);
// when(executeSpec.bind(eq("dept"), eq(mockEmployee.getDept()))).thenReturn(executeSpec);
// when(executeSpec.bind(eq("sal"), eq(mockEmployee.getSal()))).thenReturn(executeSpec);
// when(executeSpec.fetch()).thenReturn(DatabaseClient.GenericExecuteSpec.empty());
// when(executeSpec.fetch().rowsUpdated()).thenReturn(Mono.just(1)); // Simulate successful insertion
//
// // Act & Assert
// StepVerifier.create(employeeDao.saveEmployee(mockEmployee))
// .expectNextMatches(savedEmployee ->
// savedEmployee.getName().equals(mockEmployee.getName()) &&
// savedEmployee.getEmail().equals(mockEmployee.getEmail()) &&
// savedEmployee.getDept().equals(mockEmployee.getDept()) &&
// savedEmployee.getSal().equals(mockEmployee.getSal())
// )
// .verifyComplete();
//
// // Verify that the SQL query was called
// verify(databaseClient, times(1)).sql(anyString());
// verify(executeSpec, times(1)).bind(eq("name"), eq(mockEmployee.getName()));
// verify(executeSpec, times(1)).bind(eq("email"), eq(mockEmployee.getEmail()));
// verify(executeSpec, times(1)).bind(eq("dept"), eq(mockEmployee.getDept()));
// verify(executeSpec, times(1)).bind(eq("sal"), eq(mockEmployee.getSal()));
// }
//
//}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment