Throw a SerializationException instead of a NullPointerException in BuildOptions$Codec#deserialize when the given checksum does not correspond to a known BuildOptions instance. This will allow DynamicCodec to attach its normal trace to the exception, making debugging easier.

PiperOrigin-RevId: 416191547
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java
index d4b1c8b..c54c037 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java
@@ -32,6 +32,7 @@
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.util.OrderedSetMultimap;
@@ -679,12 +680,13 @@
 
     @Override
     public BuildOptions deserialize(DeserializationContext context, CodedInputStream codedIn)
-        throws IOException {
+        throws SerializationException, IOException {
       String checksum = codedIn.readString();
-      return checkNotNull(
-          context.getDependency(OptionsChecksumCache.class).getOptions(checksum),
-          "No options instance for %s",
-          checksum);
+      BuildOptions result = context.getDependency(OptionsChecksumCache.class).getOptions(checksum);
+      if (result == null) {
+        throw new SerializationException("No options instance for " + checksum);
+      }
+      return result;
     }
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildOptionsTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildOptionsTest.java
index 0e64764..32b3e5f 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildOptionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildOptionsTest.java
@@ -31,6 +31,7 @@
 import com.google.devtools.build.lib.rules.python.PythonOptions;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.TestUtils;
 import com.google.devtools.common.options.OptionsParser;
@@ -234,7 +235,7 @@
                 OptionsChecksumCache.class, new MapBackedChecksumCache()));
     Exception e =
         assertThrows(
-            RuntimeException.class, () -> TestUtils.fromBytes(deserializationContext, bytes));
+            SerializationException.class, () -> TestUtils.fromBytes(deserializationContext, bytes));
     assertThat(e).hasMessageThat().contains(options.checksum());
   }