Skip to main content

Quiz: Exception Handling and Logging

Test your knowledge on error handling and logging.

30 questions - Click on each question to reveal the answer.


Questions 1-15: Exception Handling​

Question 1: What is @ControllerAdvice?

Answer: A component that globally handles exceptions for all controllers:

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(404).body(new ErrorResponse(ex.getMessage()));
}
}

Question 2: What is the difference between @ControllerAdvice and @RestControllerAdvice?

Answer:

  • @ControllerAdvice: can return views or objects
  • @RestControllerAdvice: equivalent to @ControllerAdvice + @ResponseBody

For REST APIs, use @RestControllerAdvice.


Question 3: How to create a custom exception?

Answer:

public class ResourceNotFoundException extends RuntimeException {

private final String resourceName;
private final Object resourceId;

public ResourceNotFoundException(String resourceName, Object resourceId) {
super(String.format("%s not found with id: %s", resourceName, resourceId));
this.resourceName = resourceName;
this.resourceId = resourceId;
}

// Getters
}

Question 4: How to map an exception to an HTTP code?

Answer:

@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFound(ResourceNotFoundException ex) {
return new ErrorResponse(ex.getMessage());
}

// Or with ResponseEntity
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(ex.getMessage()));
}

Question 5: How to handle validation errors?

Answer:

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(
MethodArgumentNotValidException ex) {

Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);

return ResponseEntity.badRequest().body(errors);
}

Question 6: What is ProblemDetail (RFC 7807)?

Answer: Standard format for HTTP error responses:

@ExceptionHandler(ResourceNotFoundException.class)
public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
ProblemDetail problem = ProblemDetail.forStatusAndDetail(
HttpStatus.NOT_FOUND, ex.getMessage());
problem.setTitle("Resource Not Found");
problem.setProperty("resourceId", ex.getResourceId());
return problem;
}

JSON result:

{
"type": "about:blank",
"title": "Resource Not Found",
"status": 404,
"detail": "User not found with id: 123",
"resourceId": 123
}

Question 7: How to handle all unmanaged exceptions?

Answer:

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneric(Exception ex) {
log.error("Unexpected error", ex);

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("An unexpected error occurred"));
}

Question 8: How to add information to the error response?

Answer:

public class ErrorResponse {
private LocalDateTime timestamp;
private int status;
private String error;
private String message;
private String path;
private Map<String, Object> details;

// Constructors, getters
}

@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusiness(
BusinessException ex, HttpServletRequest request) {

ErrorResponse error = ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(HttpStatus.BAD_REQUEST.value())
.error("Business Rule Violation")
.message(ex.getMessage())
.path(request.getRequestURI())
.build();

return ResponseEntity.badRequest().body(error);
}

Question 9: How to target a @ControllerAdvice to specific controllers?

Answer:

// By annotation
@ControllerAdvice(annotations = RestController.class)

// By package
@ControllerAdvice(basePackages = "com.example.api")

// By class
@ControllerAdvice(assignableTypes = {UserController.class, OrderController.class})

Question 10: How to handle exceptions in filters?

Answer: Filters are before controllers, so @ControllerAdvice does not apply:

public class ExceptionHandlerFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) {
try {
chain.doFilter(request, response);
} catch (JwtException ex) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json");
response.getWriter().write("{\"error\":\"Invalid token\"}");
}
}
}

Question 11: How to handle async errors?

Answer:

@ControllerAdvice
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
log.error("Async error in {}: {}", method.getName(), ex.getMessage());
}
}

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

Question 12: How to throw a 404 error for a missing resource?

Answer:

@Service
public class UserService {

public User findById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.NOT_FOUND, "User not found: " + id));
}
}

// Or with custom exception
throw new ResourceNotFoundException("User", id);

Question 13: How to disable Spring Boot's default error page?

Answer:

server:
error:
whitelabel:
enabled: false

# Or customize
include-message: always
include-binding-errors: always
include-stacktrace: never
include-exception: false

Question 14: How to handle 404 errors globally?

Answer:

spring:
mvc:
throw-exception-if-no-handler-found: true
web:
resources:
add-mappings: false
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(NoHandlerFoundException ex) {
return ResponseEntity.status(404)
.body(new ErrorResponse("Endpoint not found: " + ex.getRequestURL()));
}

Question 15: What are the best practices for exceptions?

Answer:

  1. Create specific business exceptions
  2. Do not expose technical details to the client
  3. Log server exceptions
  4. Use appropriate HTTP codes
  5. Consistent response format
  6. Include a correlation ID for debugging

Questions 16-30: Logging​

Question 16: What logging framework does Spring Boot use by default?

Answer: SLF4J as a facade with Logback as the implementation.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger log = LoggerFactory.getLogger(MyClass.class);

Or with Lombok: @Slf4j


Question 17: What are the log levels?

Answer: From least to most verbose:

  1. ERROR: critical errors
  2. WARN: potentially problematic situations
  3. INFO: general information
  4. DEBUG: details for debugging
  5. TRACE: very detailed
log.error("Payment failed: {}", ex.getMessage());
log.warn("Slow query: {} ms", duration);
log.info("User {} logged in", username);
log.debug("Processing item: {}", item);
log.trace("Entering method with args: {}", Arrays.toString(args));

Question 18: How to configure log levels?

Answer:

logging:
level:
root: INFO
com.example: DEBUG
org.springframework.security: TRACE
org.hibernate.SQL: DEBUG

Question 19: Why use placeholders instead of concatenation?

Answer: Performance - the message is only constructed if the level is active:

// Good - lazy evaluation
log.debug("Processing user: {}", user);

// Bad - always evaluated
log.debug("Processing user: " + user.toString());

Question 20: How to configure Logback with an XML file?

Answer: Create src/main/resources/logback-spring.xml:

<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>

Question 21: How to write logs in JSON?

Answer: With Logstash encoder:

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>
<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

Question 22: What is MDC (Mapped Diagnostic Context)?

Answer: Thread-local context to add information to logs:

// Add at the beginning of the request
MDC.put("requestId", UUID.randomUUID().toString());
MDC.put("userId", user.getId().toString());

// In the pattern
<pattern>%d [%X{requestId}] [%X{userId}] %msg%n</pattern>

// Clear at the end
MDC.clear();

Question 23: How to implement an MDC filter?

Answer:

@Component
public class MdcFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) {
try {
MDC.put("requestId", UUID.randomUUID().toString());
MDC.put("clientIp", request.getRemoteAddr());
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}

Question 24: How to configure different logs per profile?

Answer:

<!-- logback-spring.xml -->
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>

<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="JSON"/>
</root>
</springProfile>

Question 25: How to mask sensitive data in logs?

Answer:

// Do not log sensitive data
log.info("User login: {}", user.getEmail()); // Not the password!

// Partially mask
String maskedCard = card.substring(0, 4) + "****" + card.substring(12);
log.info("Payment with card: {}", maskedCard);

// Masking pattern in logback
<pattern>%replace(%msg){'password=[^,]*','password=***'}%n</pattern>

Question 26: How to log HTTP requests?

Answer:

@Component
public class RequestLoggingFilter extends CommonsRequestLoggingFilter {

public RequestLoggingFilter() {
setIncludeQueryString(true);
setIncludePayload(true);
setMaxPayloadLength(10000);
setIncludeHeaders(false);
}
}

Or enable in config:

logging:
level:
org.springframework.web.filter.CommonsRequestLoggingFilter: DEBUG

Question 27: How to log SQL queries?

Answer:

logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.orm.jdbc.bind: TRACE # Parameters

# Or with Spring
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true

Question 28: How to archive and compress logs?

Answer:

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/app-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>

Question 29: How to send logs to an external service?

Answer: With specialized appenders:

<!-- Logstash -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash:5000</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

<!-- Or async for performance -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="LOGSTASH"/>
</appender>

Question 30: What are the best logging practices?

Answer:

  1. Use the correct log level
  2. Include context (userId, requestId)
  3. Do not log sensitive data
  4. Use placeholders
  5. Log exceptions with stacktrace
  6. Structured logs in production (JSON)
  7. Rotation and archiving
  8. Centralization for microservices

Score​

ScoreLevel
27-30Excellent - Mastered exceptions and logging
21-26Good - Some revisions needed
15-20Average - Review the chapters
Less than 15Needs review

Back to Module 10