001package com.box.sdkgen.box.errors;
002
003import com.box.sdkgen.internal.logging.DataSanitizer;
004import com.box.sdkgen.networking.fetchresponse.FetchResponse;
005import com.fasterxml.jackson.databind.JsonNode;
006import java.time.LocalDateTime;
007import java.util.Optional;
008import okhttp3.Request;
009
010public class BoxAPIError extends BoxSDKError {
011
012  public final RequestInfo requestInfo;
013
014  public final ResponseInfo responseInfo;
015
016  private final DataSanitizer dataSanitizer;
017
018  public BoxAPIError(String message, RequestInfo requestInfo, ResponseInfo responseInfo) {
019    super(message);
020    this.requestInfo = requestInfo;
021    this.responseInfo = responseInfo;
022    this.dataSanitizer = new DataSanitizer();
023  }
024
025  public static BoxAPIError fromAPICall(
026      Request request,
027      FetchResponse fetchResponse,
028      String rawResponseBody,
029      DataSanitizer dataSanitizer) {
030    RequestInfo requestInfo = RequestInfo.fromRequest(request);
031    ResponseInfo responseInfo = ResponseInfo.fromResponse(fetchResponse, rawResponseBody);
032
033    String requestId =
034        Optional.ofNullable(responseInfo.getBody())
035            .map(body -> body.get("request_id"))
036            .map(JsonNode::asText)
037            .orElse("");
038
039    return new Builder(
040            String.format("Status %d; Request ID: %s", responseInfo.getStatusCode(), requestId),
041            requestInfo,
042            responseInfo)
043        .timestamp(LocalDateTime.now().toString())
044        .dataSanitizer(dataSanitizer)
045        .build();
046  }
047
048  protected BoxAPIError(Builder builder) {
049    super(builder);
050    this.requestInfo = builder.requestInfo;
051    this.responseInfo = builder.responseInfo;
052    this.dataSanitizer = builder.dataSanitizer;
053  }
054
055  public RequestInfo getRequestInfo() {
056    return requestInfo;
057  }
058
059  public ResponseInfo getResponseInfo() {
060    return responseInfo;
061  }
062
063  public static class Builder extends BoxSDKError.Builder {
064
065    protected final RequestInfo requestInfo;
066
067    protected final ResponseInfo responseInfo;
068
069    protected DataSanitizer dataSanitizer;
070
071    public Builder(String message, RequestInfo requestInfo, ResponseInfo responseInfo) {
072      super(message);
073      this.requestInfo = requestInfo;
074      this.responseInfo = responseInfo;
075      this.dataSanitizer = new DataSanitizer();
076    }
077
078    @Override
079    public Builder timestamp(String timestamp) {
080      this.timestamp = timestamp;
081      return this;
082    }
083
084    @Override
085    public Builder error(Exception error) {
086      this.error = error;
087      return this;
088    }
089
090    @Override
091    public Builder name(String name) {
092      this.name = name;
093      return this;
094    }
095
096    public Builder dataSanitizer(DataSanitizer dataSanitizer) {
097      this.dataSanitizer = dataSanitizer;
098      return this;
099    }
100
101    public BoxAPIError build() {
102      return new BoxAPIError(this);
103    }
104  }
105
106  @Override
107  public String toString() {
108    return String.join(
109        "",
110        super.toString(),
111        String.format("\nRequest: %s", requestInfo.print(dataSanitizer)),
112        String.format("\nResponse: %s", responseInfo.print(dataSanitizer)));
113  }
114}