I posed this question a while ago, and having never received an answer I came up with my own hackadelic solution. I post it now in case it helps someone in the future. Prior to adding a layer to the map I generate an AJAX call to retrieve a single tile (via a server-side proxy). I make sure all the specific unique params that are going to be present in the OpenLayers call are present in my test call. I then simply check the result. If I get an image back I know the layer is good. If I get error XML then I can review the error text and respond accordingly. If I get a server error I know the layer itself is configured incorrectly and again I can respond accordingly.<div>
<br></div><div>Here's the Layer code to perform the validation as I wrote it, and while much of this is specific to our application the key bits are there if you want them...</div><div><br></div><div><br></div><div><div style>
/**</div><div style> *The goal here is to determine if an externally sourced WMS layer is functional. Disfunctionality</div><div style> *could take the form of a down server, an invalid config, or a bogus SLD. </div>
<div style> */</div><div style> validateExternalLayer: function(){</div><div style> </div><div style> //some trickery to get the URL to test against</div><div style> var op = this.getOpenLayersLayer(); //a fully instantiated OpenLayers.Layer.WMS object</div>
<div style> op.imageSize = new OpenLayers.Size( 256, 256 );</div><div style> op.map = this.getOpenLayersMap();</div><div style> var url = op.getURL( new OpenLayers.Bounds(-1,-1,1,1) );</div><div style>
//back em out, otherwise it will never be able to be added to the map</div><div style> op.imageSize = null;</div><div style> op.map = null;</div><div style><br></div><div style> var isValid = false;</div>
<div style> //for use within the ajax handlers</div><div style> var exLayer = this;</div><div style> </div><div style> $.ajax({</div><div style> async: false,</div><div style> timeout: 5000,</div>
<div style> url: '/assets/php/requestProxy',</div><div style> type: "POST",</div><div style> data: {</div><div style> url: url</div><div style> },</div>
<div style> complete: function( xhr, status ){</div><div style> var statusCode = xhr.status;</div><div style> var statusText = xhr.statusText;</div><div style> var contentType = xhr.getResponseHeader( "Content-Type" );</div>
<div style> var respText = xhr.responseText;</div><div style> var layerName = exLayer.getLayerInfo().name;</div><div style> if( statusCode != 200 ){</div><div style> Ext.Msg.alert("Layer Error", "The <b>" + layerName + "</b> layer cannot be properly loaded due to a server error. An error code was returned of:<br>"+ statusCode + " - " + statusText + "<br><br>This layer will be disabled.");</div>
<div style> }else{</div><div style> if( contentType == "text/html" ){</div><div style> //This content type is returned when there is a PHP error which is always a Server SLD configuration error</div>
<div style> Ext.Msg.alert("Layer Error", "The <b>" + layerName + "</b> layer cannot be properly loaded due to a configuration error.<br><br>This layer will be disabled.");</div>
<div style> }else if( contentType.indexOf( "vnd.ogc.se_xml" ) != -1 ){</div><div style> //This content type is what the WMS server returns error messages as</div><div style>
if( exLayer.getOpenLayersLayer().params.SLD ){</div><div style> //WMS generated errors are fairly random and non-specific. The only way to </div><div style> //Conclusively determine if it's an SLD problem vs something else is</div>
<div style> //to try removing the custom SLD and validate again... this usually fixes it</div><div style> delete exLayer.getOpenLayersLayer().params.SLD</div><div style>
delete exLayer.getOpenLayersLayer().params.LAYER_SLD</div><div style> </div><div style> if( exLayer.validateExternalLayer() ){</div><div style>
//The issue is with the locally defined SLD...</div><div style> Ext.Msg.alert("Layer Error", "The <b>" + layerName + "</b> layer styles cannot be properly loaded due to a WMS error. The WMS server returned:<br>'"+respText+"'<br><br>This custom styling for this layer will be disabled.");</div>
<div style> //Default back to the WMS provided legend</div><div style> exLayer.contextMenu = null;</div><div style> exLayer.getLayerInfo().useExternalLegend = true;</div>
<div style> isValid = true;</div><div style> }//There is no 'else'. Since this segment features a nested call the </div><div style> //error message will be displayed in that inner call</div>
<div style> }else{</div><div style> Ext.Msg.alert("Layer Error", "The <b>" + layerName + "</b> layer cannot be properly loaded due to a WMS error. The WMS server returned:<br>'"+respText+"'<br><br>This layer will be disabled.");</div>
<div style> }</div><div style> }else{</div><div style> isValid = true;</div><div style> }</div><div style> }</div><div style>
}</div><div style> });</div><div style> </div><div style> return isValid;</div><div style> }</div></div><div><br></div>