@@ -1856,6 +1856,108 @@ describe('OAuthProvider', () => {
1856
1856
} ) ;
1857
1857
} ) ;
1858
1858
1859
+ describe ( 'Error Handling with onError Callback' , ( ) => {
1860
+ it ( 'should use the default onError callback that logs a warning' , async ( ) => {
1861
+ // Spy on console.warn to check default behavior
1862
+ const consoleWarnSpy = vi . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
1863
+
1864
+ // Create a request that will trigger an error
1865
+ const invalidTokenRequest = createMockRequest ( 'https://example.com/api/test' , 'GET' , {
1866
+ Authorization : 'Bearer invalid-token' ,
1867
+ } ) ;
1868
+
1869
+ const response = await oauthProvider . fetch ( invalidTokenRequest , mockEnv , mockCtx ) ;
1870
+
1871
+ // Verify the error response
1872
+ expect ( response . status ) . toBe ( 401 ) ;
1873
+ const error = await response . json ( ) ;
1874
+ expect ( error . error ) . toBe ( 'invalid_token' ) ;
1875
+
1876
+ // Verify the default onError callback was triggered and logged a warning
1877
+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith ( expect . stringContaining ( 'OAuth error response: 401 invalid_token' ) ) ;
1878
+
1879
+ // Restore the spy
1880
+ consoleWarnSpy . mockRestore ( ) ;
1881
+ } ) ;
1882
+
1883
+ it ( 'should allow custom onError callback to modify the error response' , async ( ) => {
1884
+ // Create a provider with custom onError callback
1885
+ const customErrorProvider = new OAuthProvider ( {
1886
+ apiRoute : [ '/api/' ] ,
1887
+ apiHandler : TestApiHandler ,
1888
+ defaultHandler : testDefaultHandler ,
1889
+ authorizeEndpoint : '/authorize' ,
1890
+ tokenEndpoint : '/oauth/token' ,
1891
+ scopesSupported : [ 'read' , 'write' ] ,
1892
+ onError : ( { code, description, status } ) => {
1893
+ // Return a completely different response
1894
+ return new Response (
1895
+ JSON . stringify ( {
1896
+ custom_error : true ,
1897
+ original_code : code ,
1898
+ custom_message : `Custom error handler: ${ description } ` ,
1899
+ } ) ,
1900
+ {
1901
+ status,
1902
+ headers : {
1903
+ 'Content-Type' : 'application/json' ,
1904
+ 'X-Custom-Error' : 'true' ,
1905
+ } ,
1906
+ }
1907
+ ) ;
1908
+ } ,
1909
+ } ) ;
1910
+
1911
+ // Create a request that will trigger an error
1912
+ const invalidTokenRequest = createMockRequest ( 'https://example.com/api/test' , 'GET' , {
1913
+ Authorization : 'Bearer invalid-token' ,
1914
+ } ) ;
1915
+
1916
+ const response = await customErrorProvider . fetch ( invalidTokenRequest , mockEnv , mockCtx ) ;
1917
+
1918
+ // Verify the custom error response
1919
+ expect ( response . status ) . toBe ( 401 ) ; // Status should be preserved
1920
+ expect ( response . headers . get ( 'X-Custom-Error' ) ) . toBe ( 'true' ) ;
1921
+
1922
+ const error = await response . json ( ) ;
1923
+ expect ( error . custom_error ) . toBe ( true ) ;
1924
+ expect ( error . original_code ) . toBe ( 'invalid_token' ) ;
1925
+ expect ( error . custom_message ) . toContain ( 'Custom error handler' ) ;
1926
+ } ) ;
1927
+
1928
+ it ( 'should use standard error response when onError returns void' , async ( ) => {
1929
+ // Create a provider with a callback that performs a side effect but doesn't return a response
1930
+ let callbackInvoked = false ;
1931
+ const sideEffectProvider = new OAuthProvider ( {
1932
+ apiRoute : [ '/api/' ] ,
1933
+ apiHandler : TestApiHandler ,
1934
+ defaultHandler : testDefaultHandler ,
1935
+ authorizeEndpoint : '/authorize' ,
1936
+ tokenEndpoint : '/oauth/token' ,
1937
+ scopesSupported : [ 'read' , 'write' ] ,
1938
+ onError : ( ) => {
1939
+ callbackInvoked = true ;
1940
+ // No return - should use standard error response
1941
+ } ,
1942
+ } ) ;
1943
+
1944
+ // Create a request that will trigger an error
1945
+ const invalidRequest = createMockRequest ( 'https://example.com/oauth/token' , 'POST' , {
1946
+ 'Content-Type' : 'application/x-www-form-urlencoded' ,
1947
+ } ) ;
1948
+
1949
+ const response = await sideEffectProvider . fetch ( invalidRequest , mockEnv , mockCtx ) ;
1950
+
1951
+ // Verify the standard error response
1952
+ expect ( response . status ) . toBe ( 401 ) ;
1953
+ const error = await response . json ( ) ;
1954
+ expect ( error . error ) . toBe ( 'invalid_client' ) ;
1955
+
1956
+ // Verify callback was invoked
1957
+ expect ( callbackInvoked ) . toBe ( true ) ;
1958
+ } ) ;
1959
+ } ) ;
1960
+
1859
1961
describe ( 'OAuthHelpers' , ( ) => {
1860
1962
it ( 'should allow listing and revoking grants' , async ( ) => {
1861
1963
// Create a client
0 commit comments