001package Torello.Browser; 002 003import java.util.Objects; 004 005/** 006 * <H2>Represents an Error Sent by the Chrome Browser over WebSocket</H2> 007 * 008 * This class encapsulates error messages originating from the browser itself — not from the Java 009 * side, and not from transport-layer failures (like network disconnects or malformed JSON). These 010 * errors are generated by the browser's internal logic during its processing of a CDP 011 * (Chrome DevTools Protocol) command. 012 * 013 * <BR /><BR /> 014 * When the browser receives a CDP command that it cannot process correctly — due to invalid 015 * parameters, internal issues, or unrecognized method calls — it responds over the WebSocket 016 * channel with a structured error message. This message includes both an error code and a textual 017 * message describing the problem. This class captures and stores that information in a structured 018 * way, so it can be logged, analyzed, or acted upon. 019 * 020 * <BR /><BR /> 021 * Importantly, this error is not thrown as a Java exception, nor does it represent a problem in 022 * the Java-side tooling (e.g., parsing, socket I/O, etc.). It is an intentional error response 023 * issued by the browser itself, indicating that a CDP command could not be fulfilled. 024 * 025 * <BR /><BR /><BR /><B CLASS=JDDescLabel2>Registering a Handler:</B> 026 * <BR /> 027 * To receive instances of this error class, a handler must be registered at the time you create 028 * your {@link WebSocketSender} using one of the {@code createSender(...)} methods found in either 029 * {@link BrowserConn#createSender BrowserConn} or {@link PageConn#createSender PageConn}. These 030 * methods allow you to provide lambda handlers or consumer functions for error callbacks. Without 031 * explicitly setting a handler for this error type, you will never see these errors—they will be 032 * silently discarded or ignored by the internal infrastructure. 033 * 034 * <BR /><BR /> 035 * Each of the three CDP error/response types — {@link RDPError}, {@link BrowserError}, and 036 * {@link BrowserEvent} — has its own dedicated handler. These are supplied as {@code Consumer} 037 * arguments to {@code createSender(...)}, and any logic you wish to perform in response to these 038 * events must be defined there. The {@code WebSocketSender} will invoke these handlers 039 * automatically whenever it receives a message of the corresponding kind. 040 */ 041public class BrowserError 042 implements java.io.Serializable, Comparable<BrowserError> 043{ 044 /** <EMBED CLASS=external-html DATA-FILE-ID=SVUID> */ 045 protected static final long serialVersionUID = 1; 046 047 048 // ******************************************************************************************** 049 // ******************************************************************************************** 050 // Instance Fields 051 // ******************************************************************************************** 052 // ******************************************************************************************** 053 054 055 /** 056 * The numeric error code assigned by the browser for this error. 057 * 058 * <BR /><BR /> 059 * This code is defined internally by the Browser and often (but not always) maps to specific 060 * protocol-related error conditions such as "Invalid Parameters", "Target Not Found", 061 * or "Method Not Implemented." While not formally documented in all cases, the code can be 062 * used to categorize and respond to common failure cases. 063 */ 064 public final int code; 065 066 /** 067 * The textual description of the error as provided by Chrome. 068 * 069 * <BR /><BR /> 070 * This message is intended for human readability and often contains hints or clues about why 071 * the CDP command failed. It may mention an unsupported method name, a missing argument, or 072 * some kind of runtime condition that prevented the browser from fulfilling the request. 073 * 074 * <BR /><BR /> 075 * While the message is not guaranteed to follow a fixed schema, it is often specific enough to 076 * help diagnose problems—especially when debugging command payloads or execution timing. 077 */ 078 public final String message; 079 080 /** 081 * If this error was generated by a known Domain, then it will be savied into this field. If 082 * the name is not known, this field will be null. 083 */ 084 public final Domains domain; 085 086 /** 087 * If this error was generated by a known Command, then the name of that command is saved into 088 * this field. If the name is not known, this field will be null. 089 */ 090 public final String commandName; 091 092 /** The Json used to build the command. */ 093 public final String requestJSONString; 094 095 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 // Constructor 099 // ******************************************************************************************** 100 // ******************************************************************************************** 101 102 103 public BrowserError(final int code, final String message) 104 { 105 this.code = code; 106 this.message = message; 107 this.domain = null; 108 this.commandName = null; 109 this.requestJSONString = null; 110 } 111 112 @SuppressWarnings("rawtypes") 113 BrowserError(final Promise promise, final int code, final String message) 114 { 115 this.code = code; 116 this.message = message; 117 this.domain = promise.script.domain; 118 this.commandName = promise.script.commandName; 119 this.requestJSONString = promise.script.requestJSONString; 120 } 121 122 123 // ******************************************************************************************** 124 // ******************************************************************************************** 125 // java.lang.Object, Cloneable, Comarable Methods 126 // ******************************************************************************************** 127 // ******************************************************************************************** 128 129 130 public String toString() 131 { 132 final String ret = 133 "BrowserError Received:\n" + 134 "{\n" + 135 " Code: " + this.code + '\n' + 136 " Message: " + this.message + '\n'; 137 138 if (this.domain == null) return ret + '}'; 139 140 return ret + 141 " Domain: " + this.domain.getPackageName() + '\n' + 142 " Command: " + this.commandName + 143 '}'; 144 } 145 146 public int hashCode() 147 { return this.code + this.message.hashCode(); } 148 149 public boolean equals(Object other) 150 { 151 if (this == other) return true; 152 if (other == null) return false; 153 154 if (this.getClass() != other.getClass()) return false; 155 156 final BrowserError o = (BrowserError) other; 157 158 return 159 (this.code == o.code) 160 && Objects.equals(this.message, o.message) 161 && Objects.equals(this.domain, o.domain) 162 && Objects.equals(this.commandName, o.commandName); 163 } 164 165 public int compareTo(BrowserError error) 166 { 167 if (this.code != error.code) 168 return this.code - error.code; 169 170 return this.message.compareTo(error.message); 171 } 172}