<html>
    <head>
      <base href="https://bugs.webkit.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - beforeunload interoperability issues with a throwing return"
   href="https://bugs.webkit.org/show_bug.cgi?id=188696">188696</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>beforeunload interoperability issues with a throwing return
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>WebKit
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>Safari 11
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>macOS 10.13
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>Normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P2
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>HTML DOM
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>webkit-unassigned@lists.webkit.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>phistuck@chromium.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>cdumez@apple.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Assuming prior user interaction, the following code prevents a navigation, but should not -
window.onbeforeunload =
 function (e)
 {
  return {toString: function () { throw 'e' }};
 }
Also, it makes Safari briefly show an error information bar.

You can test it manually with -
<a href="https://plnkr.co/edit/PVx2JKzf0OUrOfZZ4BcR?p=preview">https://plnkr.co/edit/PVx2JKzf0OUrOfZZ4BcR?p=preview</a>
Click on the green full screen icon on the top right corner and click on the various cases and then click on "back" to attempt to trigger the beforeunload confirmation.

There is some disagreement among browsers around the edge cases.
The following ways prevent navigation (range indicates supported until) -
Way                             Chrome  Firefox Safari  Internet Explorer Edge
return                          15      3       4       6                 15
returnValue                     30      3       6.1     6                 15
preventDefault                  No      3       11      9                 15
return {toString: throw}        15 - 24 3 - 18  4*      No                No
returnValue = {toString: throw} No      No      No      9                 15

*Safari 5.1 - browser crash, Safari 10.1 and 11.1 - looks like an automatically recovering tab crash.

Note -
The tests were run using BrowserStack, so the lowest versions available are -
Firefox 3
Safari 4
Internet Explorer 6
Edge 15.
Support in prior versions cannot be determined.

Note that Chrome used to support a throwing return, but stopped. Firefox, too.
Only Microsoft browsers support a throwing returnValue.
Only Safari supports a throwing return.

My interpretation of the specification is the same for return and returnValue. The value must be converted to a DOMString when set/returned. Since it cannot be converted, the value is the initial value/undefined/null/empty string. Null and empty strings are not supposed to prevent the navigation.
I think only Firefox is currently compliant with the specification.

<a href="https://html.spec.whatwg.org/multipage/webappapis.html#onbeforeunloadeventhandlernonnull">https://html.spec.whatwg.org/multipage/webappapis.html#onbeforeunloadeventhandlernonnull</a>
<a href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#dom-beforeunloadevent-returnvalue">https://html.spec.whatwg.org/multipage/browsing-the-web.html#dom-beforeunloadevent-returnvalue</a>
<a href="https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm">https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm</a> - "If an exception gets thrown by the callback, end these steps and allow the exception to propagate" (the next step cancels the event, so that does not happen)
<a href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#prompt-to-unload-a-document">https://html.spec.whatwg.org/multipage/browsing-the-web.html#prompt-to-unload-a-document</a>


Original Chromium code review discussion -
<a href="https://chromium-review.googlesource.com/c/chromium/src/+/1154225/9..10#message-8751c40094a6e40fe00991099d5d3e71cf9c076e">https://chromium-review.googlesource.com/c/chromium/src/+/1154225/9..10#message-8751c40094a6e40fe00991099d5d3e71cf9c076e</a></pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>